垃圾收集器
serial垃圾收集器
串行的单线程垃圾收集器
进行垃圾收集的时候,需要停掉用户线程去收集垃圾,(停下来收集垃圾的过程叫做STW,stop the world)。运行在 客户端 模式(也就是我们自己的个人PC)效果较好(因为不需要多线程的切换,而且客户端对于偶尔的停顿要求会较低点。)
为什么要停掉用户线程?
打个比方(JDK官方说的例子):如果你一边扔垃圾,你妈妈一边打扫房间,这房间还能打扫干净?
CMS垃圾收集器
目标是低停顿。
整体采用 多线程并发 去执行垃圾回收。
这里并发指的是 和用户线程一起,在一个时间段内都可能被调度。
步骤有
-
初始标记
触发STW
标记一下各个区域的 GC Root。
GC ROOT:可以作为引用链的头结点的结点。
可以作为GC ROOT的结点有:
- 当前栈的局部变量表指向的对象
- 当前方法区的类指向的对象
等等。
-
并发标记
和用户线程一起,进行垃圾的标记
-
重新标记
触发STW
这个时候需要标记在并发标记中被判定的对象是否有被修改指向的问题
-
并发清除
和用户线程一起,进行垃圾的清除
优点:
低停顿。
缺点:
- 降低了用户线程的执行时间,也就是降低了吞吐量。
- 老年代采用的是标记清除算法。可能会触发FULL GC
1和3需要STW。
G1收集器
可预测的停顿,增大吞吐量,适合服务器。
把整个堆分为几个区域(region):
- Eden:年轻代
- Survivor:幸存者代
- Old:老年代
- Humongous:大对象
整体基于 标记整理, 但是由于是对于各个 region区域 进行划分的,局部上是 标记复制。
优先回收价值最大的region
步骤:
- 初始标记
- 并发标记
- 最终标记
- 筛选回收