你还不懂「JVM垃圾回收及收集器♻️(2)」么?
经典垃圾收集器
Serial收集器
- 这个收集器是一个单线程工作的收集器,但它的“ 单线 程”的意义并不仅仅是说明它只会使用一个处理器或一条收集线程去完成垃圾收集工作,
- 更重要的是强调在它进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结束。
ParNew收集器
- ParNew收集器实质上是Serial收集器的多线程并行版本
==收集器中的并发与并行==
- 并行(Parallel):并行述的是
多条垃圾收集器线程之间的关系
- 说明同一时间有多条这样的线 程在协同工作,通常默认此时用户线程是处于等待状态。
- 并发(Concurrent):并发述的是
垃圾收集器线程与用户线程之间的关系
- 说明同一时间垃圾 收集器线程与用户线程都在运行。由于用户线程并未被冻结,所以程序仍然能响应服务请求,但由于 垃圾收集器线程占用了一部分系统资源,此时应用程序的处理的吞吐量将受到一定影响。
Parallel Scavenge收集器
- 基于标记-复制算法实现的收集器,也是能够并行收集的多线程收集器
- 供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数
- 以及直接设置吞吐量大小的-XX:GCTimeRatio参数。
Serial Old收集器
- Serial Old是Serial收集器的老年代版本,
- 它同样是一个单线程收集器,使用标记-整理算法
Parallel Old收集器
- Parallel Old是Parallel Scavenge收集器的老年代版本
- 支持多线程并发收集,基于标记-整理算法实现。
CMS
- 以获取最短回收停顿时间为目标的收集器
==四个步骤==
- 初始标记(CMS initial mark)
- 并发标记(CM S concurrent mark)
- 重新标记(CM S remark)
- 并发清除(CMS concurrent sweep)
==优点==
- 并发收集、低停顿
==缺点==
- 它虽然不会导致用户线程停顿,但却会因为占用了一部分线程而导致应用程序变慢,降低总吞吐量
- 在CMS的并发标记和并发清理阶段,用户线程是还在继续运行的,
- 程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,
- CMS无法在当次收集中处理掉它们,只好留待下一次垃圾收集 时再清理掉。这一部分垃圾就称为“ 浮动垃圾”
Garbage First收集器
- 遵循
分代收集
,开创的基于Region的堆内存布局是它能够实现这个目标的关键 - 初始标记(Initial Marking):仅仅只是标记一下GC Roots能直接关联到的对象,并且修改TAMS 指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要 停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际 并没有额外的停顿。
- 并发标记(Concurrent Marking):从GC Root开始对堆中对象进行可达性分析,递归扫整个堆 里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫完成以后 , 还要重新处理SATB记录下的在并发是引用的并发对象
- 最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留 下 来 的 最 后 那 少 量 的SATB记录 。
- 筛选回收(Live Data Counting and Evacuation):负责更新Region的统计数据,对各个Region的回 收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region 构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧 Region的全部空间。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行 完成的。
作者:xiaoff
链接:https://juejin.cn/post/6994230354907234312
来源:掘金