Chrome V8系列--浅析Chrome V8引擎中的垃圾回收机制和内存泄露优化策略 (2)

目前主要有三种方法来识别指针:
1. 保守法:将所有堆上对齐的字都认为是指针,那么有些数据就会被误认为是指针。于是某些实际是数字的假指针,会背误认为指向活跃对象,导致内存泄露(假指针指向的对象可能是死对象,但依旧有指针指向——这个假指针指向它)同时我们不能移动任何内存区域。
2. 编译器提示法:如果是静态语言,编译器能够告诉我们每个类当中指针的具体位置,而一旦我们知道对象时哪个类实例化得到的,就能知道对象中所有指针。这是JVM实现垃圾回收的方式,但这种方式并不适合JS这样的动态语言
3. 标记指针法:这种方法需要在每个字末位预留一位来标记这个字段是指针还是数据。这种方法需要编译器支持,但实现简单,而且性能不错。V8采用的是这种方式。V8将所有数据以32bit字宽来存储,其中最低一位保持为0,而指针的最低两位为01

 

4.3 V8回收策略

自动垃圾回收算法的演变过程中出现了很多算法,但是由于不同对象的生存周期不同,没有一种算法适用于所有的情况。所以V8采用了一种分代回收的策 略,将内存分为两个生代:新生代和老生代

新生代的对象为存活时间较短的对象,老生代中的对象为存活时间较长或常驻内存的对象。分别对新生代和老生代使用 不同的垃圾回收算法来提升垃圾回收的效率。对象起初都会被分配到新生代,当新生代中的对象满足某些条件(后面会有介绍)时,会被移动到老生代(晋升)。

 

五、新生代算法

新生代中的对象一般存活时间较短,使用 Scavenge GC 算法。在Scavenge的具体实现中,主要是采用一种复制的方式的方法--cheney算法。

在新生代空间中,内存空间分为两部分,分别为 From 空间和 To 空间。在这两个空间中,必定有一个空间是使用的,另一个空间是空闲的。新分配的对象会被放入 From 空间中,当 From 空间被占满时,新生代 GC 就会启动了。算法会检查 From 空间中存活的对象并复制到 To 空间中,如果有失活的对象就会销毁。当复制完成后将 From 空间和 To 空间互换,这样 GC 就结束了。

 

六、老生代算法

老生代中的对象一般存活时间较长且数量也多,使用了两个算法,分别是标记清除算法标记压缩算法

在讲算法前,先来说下什么情况下对象会出现在老生代空间中:

1、新生代中的对象是否已经经历过一次 Scavenge 算法,如果经历过的话,会将对象从新生代空间移到老生代空间中。

2、To 空间的对象占比大小超过 25 %。在这种情况下,为了不影响到内存分配,会将对象从新生代空间移到老生代空间中。

老生代中的空间很复杂,有如下几个空间:

enum AllocationSpace { // TODO(v8:7464): Actually map this space's memory as read-only. RO_SPACE, // 不变的对象空间 NEW_SPACE, // 新生代用于 GC 复制算法的空间 OLD_SPACE, // 老生代常驻对象空间 CODE_SPACE, // 老生代代码对象空间 MAP_SPACE, // 老生代 map 对象 LO_SPACE, // 老生代大空间对象 NEW_LO_SPACE, // 新生代大空间对象 FIRST_SPACE = RO_SPACE, LAST_SPACE = NEW_LO_SPACE, FIRST_GROWABLE_PAGED_SPACE = OLD_SPACE, LAST_GROWABLE_PAGED_SPACE = MAP_SPACE };

在老生代中,以下情况会先启动标记清除算法:

1、某一个空间没有分块的时候

2、空间中被对象超过一定限制

3、空间不能保证新生代中的对象移动到老生代中

Mark Sweep 是将需要被回收的对象进行标记,在垃圾回收运行时直接释放相应的地址空间,如下图所示(红色的内存区域表示需要被回收的区域):

Mark Compact 的思想有点像新生代垃圾回收时采取的 Cheney 算法:将存活的对象移动到一边,将需要被回收的对象移动到另一边,然后对需要被回收的对象区域进行整体的垃圾回收。

在这个阶段中,会遍历堆中所有的对象,然后标记活的对象,在标记完成后,销毁所有没有被标记的对象。在标记大型对内存时,可能需要几百毫秒才能完成一次标记。这就会导致一些性能上的问题。为了解决这个问题,2011 年,V8 从 stop-the-world 标记切换到增量标志。在增量标记期间,GC 将标记工作分解为更小的模块,可以让 JS 应用逻辑在模块间隙执行一会,从而不至于让应用出现停顿情况。但在 2018 年,GC 技术又有了一个重大突破,这项技术名为并发标记。该技术可以让 GC 扫描和标记对象时,同时允许 JS 运行。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjdwz.html