当前位置: 首页 > Web前端 > JavaScript

垃圾回收机制

时间:2023-03-27 02:17:59 JavaScript

完整高频题库仓库地址:https://github.com/hzfe/aweso...完整高频题库阅读地址:https://febook.hzfe.org/相关问题什么是内存泄漏常见垃圾收集算法如何排查内存泄漏解答要点引用计数方法标记紧凑型(Mark-Compact)清道夫(Scavenger)GC(GarbageCollection,垃圾回收)是一种自动内存管理机制,垃圾收集器(GarbageCollector)可以自动回收分配给不再使用的程序的内存。常见的GC算法包括引用计数和标记清除。V8(JavaScript引擎,提供执行JavaScript的运行环境)的垃圾回收算法主要由Mark-Compact和Scavenger组成。深入知识点1.内存泄漏内存泄漏是指应该回收的对象没有被正常回收,成为老年代的常驻对象,导致内存占用越来越高。内存泄漏会导致应用程序速度变慢、高延迟、崩溃等。1.1内存生命周期分配:按需分配内存。用途:读写分配的内存。释放:释放不再需要的内存。1.2内存泄漏的常见原因全局变量是在没有手动回收的情况下创建的。事件侦听器/计时器/闭包等未正确清理。使用JavaScript对象进行缓存,不设置过期策略和对象大小控制。排队拥塞导致消费不及时。2.ReferenceCounting(引用计数)ReferenceCounting是一种常见的垃圾回收算法。其核心思想是保存资源(如对象)的引用次数,当引用次数为零时释放。该方法的局限性:当发生循环引用时,相互引用的对象不会被回收。3.V8垃圾回收机制V8中有两个垃圾回收器。主GC使用Mark-Compact垃圾收集算法从整个堆中收集垃圾。smallGC使用Scavenger垃圾收集算法来收集新生代垃圾。两种不同的算法处理不同的场景:Scavenger算法主要用于处理生命周期短的对象中的可访问对象。使用Mark-Compact算法处理长寿命对象中的不可访问对象。由于年轻代中幸存的可访问对象所占比例较小,而老年代中不可访问对象所占比例较小,因此这两种回收算法的结合是非常高效的。3.1分代垃圾回收在V8中,所有的JavaScript对象都是通过堆分配的。V8将它管理的堆分为两代:新生代和老年代。新一代可以细分为两个子代(Nursery,Intermediate)。即新生代中的对象是存活时间短的对象,老年代中的对象是存活时间长或常驻内存的对象。3.2Mark-Compact算法(MajorGC)Mark-Compact算法可以看作是Mark-Sweep(标记清除)算法和Cheney复制算法的结合。该算法主要分为标记、清除、排序三个阶段。图像标记(Mark)标记是找到所有可访问对象的过程。GC会递归地从一组已知的对象指针(称为根集,包括执行栈和全局对象等)中标记可访问的对象。SweepSweep是将不可访问对象留下的内存空间加入空闲列表(freelist)的过程。以后为新对象分配内存时,可以从空闲链表中重新分配。组织(紧凑型)组织是将可访问的对象移动到内存端的过程。主要解决mark-clearing阶段后,当内存空间内存碎片较多时,可能无法分配大对象,提前触发垃圾回收。3.3Scavenger算法(MinorGC)V8对新生代内存空间采用Scavenger算法,采用半空间(halfspace)设计:将堆一分为二,始终只使用一半空间:From-Space是使用空间,To-Space是自由空间。新生代在From-Space中分配对象;在垃圾回收阶段,根据需要检查并复制From-Space中可访问的对象到To-Space或老年代,释放From-Space中不可访问的对象占用的内存空间;最后,From-Space和To-Space的角色互换。参考资料内存管理Trashtalk:theOrinocogarbagecollector