-
垃圾收集器
(1) 用于回收__新生代__:
Serial:可以搭配CMS、Serial Old(MSC)使用
ParNew:可以搭配CMS、Serial Old(MSC)使用
Parallel Scavenge:可以搭配Parallel Old、Serial Old(MSC)使用
(2) 用于回收__老年代__
CMS(Concurrent Mark Sweep):可搭配Serial、ParNew、Serial Old(MSC)使用
Serial Old(MSC):可搭配Serial、ParNew、Parallel Scavenge使用
Parallel Old:可搭配Parallel Scavenge使用
(3) 用于回收__新生代、老年代__
G1(Garbage First)
-
并行和并发
并行:用户线程必须等待GC,但是GC过程本身是多线程的(用户停止扔垃圾,扫垃圾的清洁工有好几个同时扫)
并发:用户线程和GC线程同时执行(用户一边扔垃圾,清洁工一边扫垃圾)
-
Serial收集器
(1) __单线程__收集器,GC时必须停掉所有其他的工作线程,直到GC完毕
(2) 新生代GC算法是__复制算法__,老年代GC算法是__标记-整理算法__,但是一般应用场景是Client模式下的新生代GC
(3) 优点是__简单而高效__(因为会强制停掉其他工作线程),缺点是需要停顿
(4) 适用场景就是新生代、内存较小的Client模式(因为停顿时间不会很长,同时简单高效)
(5) 是Client模式下的__默认__新生代垃圾收集器
-
ParNew收集器
(1) 和Serial收集器的实现几乎完全相同,区别就是使用__多线程__进行GC,但是也要停掉其他线程
(2)新生代GC算法是__复制算法__,老年代GC算法是__标记-整理算法__,但是一般应用场景是Server模式下的新生代GC
(3) 如果是单CPU环境,那么ParNew相比Serial并没有优势(甚至可能是劣势);但是多CPU环境下可以并行GC就有优势了
(4) CMS是一款支持__并发__GC的老年代垃圾收集器,但是它只能和新生代收集器Serial、ParNew配合,所以如果是多CPU环境下就用ParNew
(5) 综上,ParNew适合Server模式下的新生代收集
-
Parallel Scavenge收集器
(1) 也是多线程并行GC(和ParNew一样),和ParNew的主要区别有两点:
1° 关注的是__吞吐量__而非__停顿时间__
2° 可以使用__自适应策略__调整参数
(2) 停顿时间:每次GC时要暂停用户线程多长时间
吞吐量: 用户代码运行时间 / (用户代码运行时间 + 垃圾收集总时间)
(3) 吞吐量和停顿时间常常是矛盾的:把新生代内存设小,那么GC一次的停顿时间肯定变小;但是意味着要经常GC,吞吐量就会下降
(4) Parallel Scavenge收集器关注的是吞吐量更高,所以适合不需要太多交互、主要在后台计算、GC发生不频繁的场合
(5) 打开 -XX:+UseAdaptiveSizePolicy参数以后,Parallel Scavange会根据系统运行情况,__自动__设置新生代大小、Eden与Survivor比例、晋升老年代对象大小等信息,无需手动设置
-
Serial Old收集器
(1) 和Serial收集器实现方式基本一样,只不过用于Client模式下的老年代回收
(2) 采取__标记-整理算法__
-
Parallel Old收集器
(1) 是对应于Parallel Scavenge收集器的老年代收集版本
-
CMS(Concurrent Mark Sweep)收集器
(1) 目标是获取最短GC停顿时间,因此采取了__并发__收集的思路
(2) 用于__老年代__的收集,使用__标记-清除算法__
(3) CMS收集器的工作过程分为4步:
1° 初始标记:要Stop the World,但是速度很快
标记GC Roots可以直接关联的对象
2° 并发标记:不用Stop the World,和用户线程并发执行
沿着GC Roots进行tracing,速度慢,但是是并发执行的
3° 重新标记:要Stop the World,速度比初始标记慢,但是比并发标记快
修正并发标记期间因为用户程序修改导致标记错误的对象
4° 并发清除:不用Stop the World,和用户线程并发执行
将死亡的对象清除掉,使用的是标记-清除算法
(4) 优点:耗时长的2个步骤(并发标记、并发清除)都是和用户线程并发执行的,所以GC停顿时间短
(5) 缺点
1° 对CPU资源非常敏感
虽然可以并发执行,但是总要使用CPU来进行GC,所以CPU资源不足时会和用户线程竞争,影响用户线程的执行速度
2° 无法处理浮动垃圾
由于并发清除的过程是一边在清理垃圾,一边用户线程还在产生垃圾,所以老年代要预留内存空间给清理时使用,不能像其他垃圾收集器一样等到老年代快满的时候再清理。
这样诱发的问题是:老年代要设定一个阈值,空间占有率达到阈值后就要清理。如果这个阈值设的很小,那么要经常清理;如果阈值设的很大,可能在清理垃圾时导致用户产生的垃圾溢出了剩余空间,这时引发__“Concurrent Mode Failure”__。这个时候就要使用Serial Old来处理这种失败的情况进行GC,这也就是CMS要使用Serial Old的原因。
3° 内存空间碎片
CMS采用标记-清除算法,会产生空间碎片。设置-XX:+UseCMSCompactAtFullCollection开关可以在发生Full GC时开启内存碎片的整理过程,但是停顿时间会变长
-
G1(Garbage First)收集器
(1) 特点
1° 并行与并发
多线程收集,并且GC中的很多步骤可以和用户线程并发执行
2° 分代收集
使用G1收集器时,Java堆的内存布局和其他收集器很不一样:不再明确在物理上划分出新生代和老年代(一般来讲新生代的空间远小于老年代,而且GC更频繁),而是将堆划分成很多个__Region__,新生代和老年代都是一部分Region的集合,但是GC时的思想仍然是分代进行收集
3° 空间整合
局部(两个Region之间)采用__复制算法__,整体采用__标记-整理算法__,避免了CMS收集器的内存空间碎片的问题
4° 可预测的停顿
相比Parallel Scavenge/Parallel Old,G1最大的特点是可以根据用户设置的最大GC停顿时间完成GC
(2) 步骤
1° 初始标记:和CMS的初始标记差不多
2° 并发标记:和CMS的并发标记差不多
3° 最终标记:和CMS的重新标记差不多
4° 筛选回收:
这个是G1收集器的特色部分,它首先对所有Region进行一下回收价值和回收时间的判断,然后根据用户指定的GC暂停时间,决定从哪个Region开始回收:在满足GC停顿时间的前提下,优先回收价值大的Region(所以叫Garbage First)
(3) G1收集器最大的优势在于GC停顿时间可预测,而且它不需要和其他收集器配合,一个收集器完成新生代+老年代的收集,只不过内存中的结构变了
-
总结一下以上的__7种__收集器:
最简单的、也是默认的新生代收集器是__Serial__,它对应的老年代收集器是__Serial Old__;但是Serial/Serial Old的缺陷是单线程回收,于是出现了多线程并行回收的__ParNew__;另一个多线程并行回收的收集器__Parallel Scavenge__剑走偏锋,其他收集器关注点在停顿时间,而它关注点在吞吐量;曾经Parallel Scavenge没有对应的老年代收集器,Serial/ParNew/Parallel Scavenge都只能用Serial Old作为老年代收集器;后来__CMS__横空出世,做到了并行+并发回收老年代,然而CMS只支持Serial和ParNew,不支持Parallel Scavenge;终于__Parallel Old__诞生了,作为Parallel Scavenge对应的老年代收集器;最后,__G1__作为收集器最新成果,革新了Java堆内存的分布方式(Region块),可以一个收集器完成新生代+老年代的GC,并且还提供了可预测的GC时间
-
垃圾收集器参数
UseSerialGC:Client模式下的默认值,使用Serial+Serial Old
UseParNewGC:使用ParNew+Serial Old
UseConcMarkSweepGC:使用ParNew+CMS+Serial Old(Serial Old作为CMS回收失败后的备选)
UseParallelGC:Server模式下的默认值,使用Parallel Scavenge+Parallel Old
SurvivorRatio:Eden与Survivor的比值
PretenureSizeThreshold:直接晋升到老年代的对象大小阈值
MaxTenuringThreshold:晋升到老年代的对象年龄阈值
ParallelGCThreads:并行GC时允许进行GC的线程数
GCTimeRatio:使用Parallel Scavenge时允许的吞吐量(GC时间占总时间比例)
MaxGCPauseMillis:使用G1时的最大停顿时间
CMSInitiatingOccupancyFraction:使用CMS时老年代空间使用多少时触发GC
UseCMSCompactAtFullCollection:使用CMS时完成GC后是否清理碎片
CMSFullGCsBeforeCompaction:使用CMS时进行几次GC后来一次碎片清理
chapter03_垃圾收集器与内存分配策略_5_垃圾收集器
最新推荐文章于 2024-08-05 00:10:02 发布