JS 垃圾回收机制
作者:互联网
垃圾回收机制
内存的生命周期
内存,临时存储数据的空间,读写快。数据本身是二进制,代表特定信息,变量是内存的标识。
内存生命周期
分配小内存空间,得到使用权 → 存储数据,可以反复操作 → 释放空间。
内存常见问题
内存溢出
当程序运行需要的内存超过了剩余的内存时,就抛出内存溢出的程序错误。
内存泄漏
占用的内存没有及时释放,内存泄漏积累多了就容易导致内存溢出。
-
常见原因
- 意外的全局变量
- 被遗忘的计时器或回调函数
- 脱离 DOM 的引用
- 闭包
内存膨胀
应用程序本身需要很大的内存空间,当前设备本身硬件不支持造成的性能上差异。
何为JS垃圾
一是变量在使用完后上下文里不再需要它;
二是当前程序运行时,变量不能被引用到。
可达对象:能访问到(通过具体的引用或在当前的上下文中通过作用域链)的对象。
垃圾回收机制(garbage collection mechanism,简称GC)
GC方法
引用计数法
-
当声明一个变量并给该变量赋值一个引用类型的值时候,该值的计数+1,当该值赋值给另一个变量的时候,该计数+1,当该值被其他值取代的时候,该计数-1,当计数变为0的时候,说明无法访问该值了,垃圾回收机制清除该对象。
-
只要这个控件即将被占满时,GC就开始工作。
-
优点
- 立即进行回收;
- 最大限度的减少程序的暂停,防止内存溢出。
-
缺点
- 当两个对象循环引用的时候,引用计数无计可施。
- 时间开销大,时刻监控对象的引用数字。
标记清除法
- 分为两个阶段:
- 遍历所有对象找到可达对象进行标记;
- 仍然遍历所有的对象,把没有标记的对象进行清除,也会把第一阶段设置的标记抹掉。
- 最后会把回收的空间直接放在空闲列表上,方便后续程序直接申请使用。
- 对象会采用递归的方式向子元素继续寻找可达对象。
- 优点:解决对象循环引用的回收操作。
- 缺点:释放的空间地址可能不连续,即空间的碎片化。
标记整理法
在标记清除法基础上,清除之前先执行整理操作,移动对象的位置,形成连续地址。
v8引擎
- 采用及时编译,可以将源码翻译成直接执行的机器码。
- 内存上限64位-1.5G、32位-800M。
- 分代回收机制,将内存分为了新生代和老生代。
新生代 :64位-32M、32位16M。
老生代:64位-1.4G、32位-700M、
存活时间短的,新创建的对象或者只经历过一次的垃圾回收的对象被称为新生代。
存活时间长的,经历过多次垃圾回收的对象被称为老生代。 - 新生代:复制算法 + 标记整理法
- 被分为 From(使用状态) 和 To(空闲状态) 两个大小相同的空间。
- 当 From 空间满时执行标记整理法,执行完后将活动对象拷贝到To空间,把From空间完全释放。最后,把From和To进行空间交换。
- 新生代↗老生代的条件: - 第一个是判断是对象否已经经过一次GC。若经历过,则将对象从 From 空间复制到老生代中;若没有经历,则复制到 To 空间。
- 第二个若 To 空间使用超过 25%,则对象直接晋升到老生代中。设置 25% 的原因主要是因为算法结束后,两个空间结束后会交换位置,如果 To 空间的内存太小,会影响后续的内存分配。
- 老生代:标记清除法 + 标记整理法 + 增量标记法
- 标记清除法完成垃圾控件的释放和回收,标记整理法用于新生代复制到老生代时,老生代存储区域空间不足存放新对象时。
- 增量标记优化GC,将整段的垃圾回收操作分成多个小步骤,组分片完成整个回收。
- 垃圾回收与程序执行交替完成(比如递归遍历分组),不会长时间暂停程序执行,用户体验较为流畅。
标签:标记,对象,回收,JS,内存,老生,垃圾 来源: https://blog.csdn.net/m0_56598099/article/details/121263938