JVM垃圾收集器
2021-04-05 10:06:45 0 举报
目前存在的各种垃圾收集器介绍和新生代与老年代的垃圾收集组合
作者其他创作
大纲/内容
用户线程4
用户线程1
用户线程2
GC线程1
用户线程3
GC线程4
* 初始标记:标记一下GC ROOT能直接关联到的对象并且修改TAMS的值,让下一阶段用户线程并发运行时能在正确可用的Region中创建对象,需要停顿线 程,但耗时很短。* 并发标记:从GC Roots开始对堆中对象进行可达性分析,找出存活对象,耗时很长,但是可以和用户线程并发执行。* 最终标记:为了修正在并发标记阶段因用户线程继续运作而导致标记产生变动的那一部分记录,虚拟机将这一阶段对象变化记录在线程Remembered Set Logs里 面,最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中,需要停顿线程,但是可以并行执行。* 筛选回收:首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来指定回收计划优点:并行与并发、分代收集、空间整合、可预测的停顿
并发标记
Serial Old(MSC)
GC线程
Region
老年代采用标记-整理算法暂停所有线程
重新标记
和ParNew很像,但Parallel是吞吐量优先的垃圾收集器+XX:MaxGCPauseMillis 设置最大垃圾收集停顿时间(牺牲吞吐量和新生代空间换取的)。设置的过小一次GC时间缩短了,但是GC会很频繁+XX:GCTimeRatio 直接设置吞吐量大小+XX:+UseAdaptiveSizePolizy 开关参数,打开之后不需要设置新生代与老年代的就参数,Parallel会自适应调节,这也是与ParNew收集器的一个重要区别
年轻代
新生代采用复制算法,暂停所有用户线程
GC线程2
最终标记
Safepoint
整体看是基于标记整理算法实现,局部(两个Region)上来看是基于复制算法实现
多线程版本
s1(1/10)
重置线程
3)CMS收集器会出现内存碎片问题。基于标记清除算法实现,为了解决空间碎片问题,在CMS顶不住要进行Full GC时开启内存碎片的合并整理过程,内存整理过程是并发的,空间问题没有了,但停顿时间又变长了;也可以设置多少次不压缩的Full GC后,跟着来一次带压缩的(默认为0,表示每次进入Full GC时都进行碎片整理)
垃圾收集器
标记一下GC ROOT能直接关联到的对象,暂停所有用户线程
Remembered Set
用户线程执行区域
ParNew
堆
筛选回收
CMS
初始标记
单线程收集器
s0(1/10)
老年代(2/3)
GC线程3
并发清理
Eden(8/10)
吞吐量 = 运行用户代码时间 / (运行用户代码时间 + 垃圾收集时间)
Serial
老年代
G1
1)CMS对CPU资源非常敏感,在并发标记和清理阶段,虽然不会导致所有用户线程停顿,但是会因为占用了一部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。CMS默认开启的回收线程数是(CPU数量+3)/4。为了解决这一问题,实行和单CPU年代PC机操作系统使用抢占式来模拟多任务的思想一样,就是在并发阶段让GC线程、用户线程交替运行,尽量减少GC线程独占线程的时间,但是效果一般,目前版本已不再提倡用户使用
2)CMS收集器无法处理浮动垃圾,可能出现\"Concurrent Mode Failure\"失败而导致另一次Full GC的产生。由于并发清理阶段用户线程还在运行,自然还会产生新的垃圾,但是这一部分垃圾出现在标记过程之后,清理不掉,称为浮动垃圾。需要预留空间给用户线程使用
ParallelScavenge
ParallelOld
新生代
Stop The World
后备预案
记录不同Region之间的对象引用关系
标记一下GC ROOT能直接关联到的对象并且修改TAMS的值,暂停所有用户线程
0 条评论
下一页