基础系列-垃圾回收机制
垃圾回收
执行环境负责代码执行时管理内存。
通过自动内存管理实现内存分配和闲置资源回收。
基本思路:确定哪个变量不会再使用,然后释放它占用的内存。这个过程是周期性的,即垃圾回收程序每隔一定时间(或者说在代码执行过程中某个预定的收集时间)就会自动执行。
以函数中局部变量的正常生命周期为例。函数中的局部变量会在函数执行时存在。此时,栈(或堆)内存会分配空间以保存先相应的值。函数在内部使用了变量,然后退出。此时,就不再需要那个局部变量了,它占用的内存可以释放,供后面使用。
垃圾回收标记策略
标记请理
最常用。
垃圾回收程序运行时,
- 会标记内存中存储的所有变量
- 会将在所有上下文中的变量(全局变量),以及被在上下文中的变量引用的变量的标记去掉。
- 在此之后被加上的标记的变量就是待删除的(任何在上下文中的变量都访问不到它们了)。
- 垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。
当变量进入上下文时,这个变量会被加上存在于上下文中的标记。
当变量离开上下文时,会被家上离开上下文的标记。
引用计数
跟踪记录每个值被引用的次数。
当声明了一个变量并将一个引用类型的值赋值给该变量时,则这个值得引用次数就是1。如果同一个值又被赋给另一个变量,则该值的引用次数加1。
如果包含对这个值引用的变量又取得另外一个值,则这个值的引用次数减1。
当这个值的引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。
存在的问题:循环引用(对象A有个指针指向对象B,对象B也引用了对象A)
管理内存
内存限制目的是防止运行 JavaScript 的网页耗尽全部系统内存而导致系统崩溃。
内存限制问题不仅会影响给变量分配内存,同时还会影响调用栈以及在一个线程中能够同时执行的语句数量。
优化占用内存的最佳方式
为执行中的代码只保存必要的数据。
一旦数据不再有用,最好通过将其值设置为 null 来释放引用(解除引用)
这个做法适用于大多数全局变量和全局对象的属性。局部变量会在它们离开执行环境时自动被解除引用。
解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。(不是立即回收)