基础系列-垃圾回收机制

垃圾回收

执行环境负责代码执行时管理内存。

通过自动内存管理实现内存分配和闲置资源回收。

基本思路:确定哪个变量不会再使用,然后释放它占用的内存。这个过程是周期性的,即垃圾回收程序每隔一定时间(或者说在代码执行过程中某个预定的收集时间)就会自动执行。

以函数中局部变量的正常生命周期为例。函数中的局部变量会在函数执行时存在。此时,栈(或堆)内存会分配空间以保存先相应的值。函数在内部使用了变量,然后退出。此时,就不再需要那个局部变量了,它占用的内存可以释放,供后面使用。

垃圾回收标记策略

标记请理

最常用。

垃圾回收程序运行时,

  1. 会标记内存中存储的所有变量
  2. 会将在所有上下文中的变量(全局变量),以及被在上下文中的变量引用的变量的标记去掉。
  3. 在此之后被加上的标记的变量就是待删除的(任何在上下文中的变量都访问不到它们了)。
  4. 垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

当变量进入上下文时,这个变量会被加上存在于上下文中的标记。

当变量离开上下文时,会被家上离开上下文的标记。

引用计数

跟踪记录每个值被引用的次数。

当声明了一个变量并将一个引用类型的值赋值给该变量时,则这个值得引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。

如果包含对这个值引用的变量又取得另外一个值,则这个值的引用次数减1。

当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。

存在的问题:循环引用(对象A有个指针指向对象B,对象B也引用了对象A)

管理内存

内存限制目的是防止运行 JavaScript 的网页耗尽全部系统内存而导致系统崩溃。

内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。

优化占用内存的最佳方式

为执行中的代码只保存必要的数据。

一旦数据不再有用,最好通过将其值设置为 null 来释放引用(解除引用)

这个做法适用于大多数全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用。

解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。(不是立即回收)