当前位置: 首页 > 后端技术 > Node.js

V8垃圾回收机制

时间:2023-04-03 23:52:34 Node.js

原文地址这篇文章是深入浅出解释nodejs的学习笔记的一部分这个限制可以通过传递--max-old-space-size和--max-new-space-size来调整whennode启动,如:node--max-old-space-size=1700app.js//单位是MBnode--max-new-space-size=1024app.js//单位是MB以上参数在V8初始化时生效,一旦生效,不能动态更改。V8垃圾回收机制的内存分代V8在V8中主要将内存分为新生代和老年代。新生代中的对象是存活时间短的对象,老年代中的对象是存活时间长或常驻内存的对象。V8堆的总大小是新生代使用的内存加上老年代所有的内存。前面提到的--max-old-space-size用于设置老年代内存空间的最大值,--max-new-space-size用于设置老年代内存空间的最大值新一代。新一代Scavenge算法中的对象主要是通过Scavenge算法进行垃圾回收。在Scavenge的具体实现中,主要使用了Cheney算法。切尼算法是一种通过复制实现的垃圾回收算法。它将堆内存一分为二。两个空间中只有一个在使用中,另一个闲置。使用中的空间称为From空间,闲置的空间称为To空间。分配对象时,首先在From空间分配对象。当垃圾回收开始时,From空间中存活的对象被检查并复制到To空间,同时非存活对象占用的空间被释放。复制完成后,From空间和To空间的角色互换。简而言之,垃圾回收的过程就是将存活的对象复制到两个空间中。Scavenge算法的缺点是只能使用堆内存的一半。但由于它只复制幸存的物体,幸存的物体只占场景的一小部分,生命周期较短,因此在时间效率上有出色的表现。以上是在纯Scavenge算法中,但是在分代垃圾回收的前提下,From空间中的存活对象在复制到To空间之前需要进行检查。对象被移动到老年代,这个过程称为对象提升。对象提升有两个条件,一是对象是否经历过Scavenge回收:二是当To空间的使用率超过25%时,则直接将对象提升到老年代空间。对于老年代Mark-Sweep和Mark-Compact的对象,由于存活对象比例较大,使用Scavenge方式会存在两个问题:一是存活对象较多,复制效率低存活的对象会减少;另一个是仍然是浪费了一半空间的问题。为此,V8在老年代主要采用Mark-Sweep和Mark-Compact的组合进行垃圾回收。Mark-Sweep是标记清除的意思,分为标记和清除两个阶段。与Scavenge相比,Mark-Sweep并没有将内存空间一分为二,因此不会出现浪费一半空间的行为。不同于Scavenge复制活对象,Mark-Sweep在标记阶段遍历堆中的所有对象,对活对象进行标记。在随后的清理阶段,只有没有被标记的对象才会被移除。可以看出Scavenge只复制活对象,而Mark-Sweep只清理死对象。活对象只占新生代的一小部分,死对象只占老年代的一小部分,这也是为什么这两种回收方式都能高效处理的原因。老年代空间标记后Mark-Sweep示意图:Mark-Sweep最大的问题是在进行clearmark后,内存会出现不连续的状态,这会导致分配失败largeobject需要稍后分配,垃圾收集会提前开始,而这个收集是不必要的。为了解决Mark-Sweep的内存碎片问题,提出了Mark-Compact。它是在Mark-Sweep的基础上发展而来的。不同的是对象被标记为死亡后,在排序的过程中,活着的对象会被移动到一端,移动完成后,直接清理边界外的对象。3种回收算法的简单比较:回收算法Mark-SweepMark-CompactScavengeModerateSpeedSlowestFastestSpaceoverheadLess(withfragments)Less(nofragments)Doublespace(nofragments)是否移动对象NoYes如果大家都认同美股有兴趣的也可以点击美股指南