文章目录
GC分类和性能指标
- 线程数
- 串行垃圾回收器
- 并行垃圾回收器
- 工作模式
- 并发式垃圾回收器
- 独占式垃圾回收器
- 碎片处理
- 压缩式垃圾回收器(进行压缩整理)
- 非压缩式垃圾回收器
- 工作内存区间
- 年轻代垃圾回收器
- 老年代垃圾回收器
性能指标:
-
吞吐量:运行用户代码的时间占总运行时间的比例
-
暂停时间:STW的时间
-
内存占用:Java堆区所占用的内存大小
-
*垃圾收集开销:吞吐量的补数
-
*收集频率:收集操作发生的频率
-
*快速:一个对象从诞生到被回收所经历的时间
在最大吞吐量优先的情况下,降低停顿时间
不同垃圾回收器的概述
官方文档:https://www.oracle.com/technetwork/java/javase/tech/memorymanagement-whitepaper-1-150020.pdf
垃圾回收器和分区
年轻代收集器:Serial GC 、Parallel Scavenge GC 、ParNew GC
老年代收集器:Serial Old GC 、 Parallel Old GC 、CMS GC
整堆收集器:G1 GC
垃圾收集器的组合关系
Serial回收器 : 串行回收
Serial收集器采用复制算法、串行回收和STW机制的方式执行内存回收
Serial Old收集器采用的是标记-压缩算法
Serial GC在年轻代、Serial Old GC在老年代
ParNew回收器 : 并行回收
对于新生代,回收频率高,使用并行方式更高效。
对于老年代,回收次数少,使用串行方式节省资源。(无需切换线程)
Parallel回收器 : 吞吐量优先
jdk8 默认垃圾回收器
与ParNew不同,Parallel Scabenge的目标是达到一个可控制的吞吐量,并且Parallel Scavenge可以动态调整内存分配情况——自适应调节策略
高吞吐量可以高效利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。
Parallel Old老年代,采用标记-压缩算法。
CMS回收器 (Concurrent Mark Sweep GC): 低延迟
并发收集器,实现了垃圾收集线程与用户线程同时工作。
由于低延时性,适合与用户交互的程序。
初始标记:所有工作线程会STW,这个阶段仅仅只是标记处GC Roots能直接关联到的对象。一旦标记完成之后就会恢复之前被暂停的应用。由于直接关联的对象比较小,所以速度非常快。
并发标记:从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程。
重新标记:修正并发标记期间,因为用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,会发生STW。只能判断并发标记过的对象是否现在仍然是垃圾对象。
并发清除:清理删除掉标记阶段判断已经死亡的对象,释放内存空间。
当堆内存使用率达到某一阈值时,开始进行回收,如果运行期间CMS运行失败了(用户线程占用内存速度远超CMS),会临时启动后备方案——Serial Old来重新进行老年代的垃圾收集。
优点:
- 并发收集
- 低延迟
缺点:
- 会产生内存碎片,采用标记清除算法,可能无法分配大对象
- CMS收集器对CPU资源非常敏感。由于占用用户线程用于垃圾回收,因此吞吐量降低
- CMS收集器无法处理浮动垃圾。并发标记过程中用户线程产生的新的对象,重新标记无法判断这个过程中产生的新的垃圾,因此回导致这些新产生的垃圾无法及时被回收。
⭐G1回收器 : 区域化分代式
G1回收器概述
在延迟可控的情况下获得尽可能高的吞吐量
并行回收器,它把堆内存分割为不相关的区域(Region)。使用不同的Region来表示Eden、S0、S1、老年区。
G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region
-XX:+UseG1GC
特点:
并行与并发
G1回收器在工作期间是并行与并发并存的,并行时可以充分的利用内存,但是此时用户线程会发生STW。而并发在一般情况下不会再整个回收阶段发生完全堵塞应用程序的情况
分代收集
G1属于分代型垃圾回收器。但是在空间分配上不再要求年轻代和老年代空间连续,也不必是固定大小和固定数量。
空间整合
内存回收是以Region作为基本单位的。Region之间是复制算法,但是整体可看作是标记-压缩算法。
可预测的停顿时间模型
可以建立可预测的停顿时间模型,能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
常用参数设置
参数 | 描述 |
---|---|
-XX:+UseG1GC | 手动指定使用G1收集器 |
-XX:G1HeapRegionSize | 设置每个Region的大小。值为2的幂,范围是1MB到32MB,默认为堆内存的1/2000 |
-XX:MaxGCPauseMills | 设置期望达到的最大GC停顿时间指标,默认是200ms |
-XX:ParallelGCThread | 设置并行线程数,最多为8 |
-XX:ConcGCThread | 设置并发标记的线程数。设置为ParallelGCThread的1/4左右 |
-XX:InitiatingHeapOccupancyPercent | 设置触发并触发GC周期的Java堆占用率阈值。超过此值,就触发GC。默认为45 |
使用步骤
1.开启G1垃圾收集器
2.设置堆最大内存
3.设置最大的停顿时间
G1回收器垃圾回收过程
- 年轻代GC(Young GC)
- 老年代并发标记过程(Concurrent Marking)
- 混合回收(Mixed GC)
- Full GC 为GC评估失败提供了一种保护措施,即强力回收
当年轻代的Eden区用尽时开始年轻代回收过程,是一个并行的独占式收集器,从年轻代区间移动存活对象到Survivor区或老年区;
当堆内存达到一定值(默认45%)时,开始老年代并发标记过程;
标记完成开始混合回收过程,G1从老年区移动存活对象到空闲区间,这些空闲区间也成为了老年代的一部分,G1的老年代回收与其他GC不同,不需要整个老年代被回收,一次只需要扫描/回收一小部分老年代的Region就可以了。同时老年代Region是和年轻代一起被回收的。
垃圾回收总结
最小化内催和并行开销:Serial GC
最大化应用程序吞吐量:Parallel GC
最小化GC中断或停顿时间:CMS GC
GC日志分析
打印GC日志信息
-Xloggc:./logs/gc.log
GC日志分析工具
垃圾回收器的新发展
Shenandoah GC、ZGC 主打低延迟
Shendandoah垃圾回收器的暂停时间与堆大小无关,都可以把垃圾收集的停顿时间限制在10毫秒内。但是吞吐量有明显的不足。
⭐ZGC 基于Region布局,可并发的标记-压缩算法,以低延迟为首要目标