Chrome的垃圾回收机制
2021-7-17
| 2023-2-19
0  |  0 分钟
password
Created
Feb 16, 2023 11:01 AM
type
Post
status
Published
date
Jul 17, 2021
slug
summary
Chrome(本质上是V8)的垃圾回收被设计成了两个区块 • 新生代区: 负责大部分临时对象的处理 • 老生代区: 对于数次新生代中没有清除掉的对象, 会被转入这个区, 老生代区中的对象的GC频率会降低
tags
Chrome
垃圾回收
category
原理
icon
 
chrome中其实大多数对象的生存周期都很短. 基本经过一次GC之后, 就会被释放掉.
而只有少部分的对象, 其生存周期很长, 相应的, 我们不需要对齐进行多次检测和判断
 
因此Chrome(本质上是V8)的垃圾回收被设计成了两个区块
  • 新生代区: 负责大部分临时对象的处理
  • 老生代区: 对于数次新生代中没有清除掉的对象, 会被转入这个区, 老生代区中的对象的GC频率会降低
 

新生代区

因为其GC频次高, 因此占用的内存则很少, 以便快速进行遍历和清除工作
新生代中使用了Scavenge算法来进行无用临时对象的清除工作
  • Scavenge算法是一个典型的空间换时间的复制算法, 在空间占用不大的场景下非常实用.
 
Scavenge算法将新生代分为两个区块(from-space to-space), 在GC工作过程中, 会将from-space中的活动对象, 复制到to-space中. 此时from-space清空, 变成to-space. 对应的to-space会变成from-space. 重复此流程.
 
如何区分活动对象和非活动对象?
从根集遍历, 如果这个对象被搜索到引用, 则代表未活动对象, 否则则为非活动对象
 
在什么时机会将新生代放到老生代?
新生代中具体又区分了两个区: nursery区和intermediate区. 在活动对象复制的过程中, 会将其复制到to-space的intermediate区. 当下次复制时, 如果发现复制的对象在intermediate区. 则将其放到老生代区.
 

老生代区

在老生代空间中采用了 Mark-Sweep(标记清除) 和 Mark-Compact(标记整理) 算法
 
  • Mark-Sweep 标记清除
与新生代所不同的是, 老生代中主要是活动对象, 因此需要标记活动对象, 并将其操作清除掉.
标记清除主要分为两个阶段:
  1. 标记阶段: 将老生代进行第一次扫描, 标记活动对象
  1. 清理阶段; 清除未被标记的对象
 
被清除的对象遗留下了小片小片的内存空间, 为了保证内存空间的有效利用, 因此还需要进行内存空间的整理, 也就是标记整理
  • Mark-Compact 标记整理
将所有的活动对象整理成无空余内存空间碎片的内存区, 以有效利用内存占用.
 

全停顿

因为期间需要进行活动对象的移动处理, 在这期间是无法进行任何的JS逻辑操作的, 这个过程被称为全停顿.
如果老生代对象多且大, 那么全停顿的时间就会变长, 页面就会显得卡顿.
 

Orinoco优化

核心目的是为了降低全停顿导致卡顿的问题
主要使用: 增量标记, 惰性清理, 并发, 来降低全停顿的影响
 

增量标记

将全量标记拆分成一个个任务, 穿插在js逻辑之间执行. 类似于react的fiber的机制

惰性清理

当当前可用内存足够时, 可以将清理延后一些, 让js逻辑先执行

并发

辅助线程执行GC的标记等流程, 仅最后操作对象时占用主线程

并行

辅助线程和主线程同时进行不干扰的GC活动, 以降低主线程时间
 

参考:
深入理解Chrome V8垃圾回收机制
Updated Aug 25, 2023

原理
  • Chrome
  • 垃圾回收
  • SOLID原则直播背后使用的技术
    目录