ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 什么场景下gc很重要 - 内存需要被反复利用的场景 - 大量的对象在被分配和回收 - 高并发场景 ## 标记(Mark-Sweep)算法 ![](https://img.kancloud.cn/e2/c7/e2c772ae72dccab8fa4ad70923aab239_800x556.png) - 栈中分配的对象存入一个集合中( Root set) - 每次遍历 Rootlet中的对象追溯Heap中的对象进行分析 - 分成两个阶段标记(Mark)和清扫( Sweep)阶段 - Mak负责标记在使用的对象 - Sweep负责删除不被使用的对象 **Mark 阶段** ![](https://img.kancloud.cn/6e/f7/6ef7d06f36964fb6851f72bd785d1036_400x281.png) **Sweep阶段** ![](https://img.kancloud.cn/9f/ca/9fca73222b6cd8d6492610c8517c5b1b_400x272.png) 删除没有被标记的对象 ## gc时程序状态 ### STP(Stop The World) 模型 ![](https://img.kancloud.cn/ad/6a/ad6a1feda95f6ed9764605587b6bb243_400x81.png) 执行时每一个阶段,都要全部执行完全 ### Increment Update 模型 ![](https://img.kancloud.cn/62/e7/62e7b5fccb9415bc03e1da6332a89d56_400x58.png) 每个阶段多次执行 ## Stop-the-world 问题 很难做到不STW,但是可以考虑缩短STW的时间,让用户感知到的是一个连续的模型 ## 三色标记 go 使用 三色 白色:需要回收 黑色:不回收 灰色:中间地带 Root->白->灰 扫描 root set,找到白色节点标记成灰色 ![](https://img.kancloud.cn/a9/84/a984839a72ba07e8404196f732aa76dd_400x278.png) 灰->黑 以灰色节点为起始点,做一次BFS。之前的灰色节点标黑,剩下的白色节点就是需要回收的 ![](https://img.kancloud.cn/c0/c3/c0c30d637a21234c43d5f90abbc8731d_400x271.png) ![](https://img.kancloud.cn/6a/be/6abe6229a585d7d5aedd61264401a581_400x272.png) **会不会有 mutation违反性质** - 方法 - 读取白色节点时增加一个读屏障( read barrier),禁止读取 - 改变一个黑色节点时增加一个写屏障 write barrier),写入结束后,将这个节点标记成为灰色。 - 严格保证了不会有黑色节点指向白色节点。