Java JVM的学习-04 GC垃圾回收 (下)

上接: Java JVM的学习-03 GC垃圾回收 (上)

垃圾回收器

JVM常见垃圾回收器分为以下7种:
新生代垃圾回收器
1.Serial
2.ParNew
3.Parallel Scavenge
老年代垃圾回收器
1.Serial Old
2.Parallel Old
3.CMS
还包括 G1

一、新生代垃圾回收器

1. Serial
Serial是采用复制算法单线程回收器,在其执行的时候回调停其他线程,避免在处理过程中产生新的垃圾。
-XX:+UserSerialGC 选择Serial垃圾回收器
Java JVM的学习-04 GC垃圾回收 (下)
2. ParNew
将Serial回收阶段换为多线程,其他与Serial无异
默认开启线程数与CPU数目一致,常应用于多核服务器
-XX:ParallelGCThreads 设置线程数目
-XX:+UseParNewGC 选择ParNew 回收器
Java JVM的学习-04 GC垃圾回收 (下)
3. Parallel Scavenge
Parallel Scavenge也是一款作用于新生代多线程回收器,与ParNew不同的是,ParNew更注重缩短用户线程的等待时间,而Parallel Scavenge在乎吞吐量。
所谓吞吐量就是CPU执行用户线程的时间在执行总时间的占比。
GC处理的频率和处理时间都会影响吞吐量。
-XX:MaxGCPauseMillis 用来控制回收尽可能在多长时间内完成
-XX:GCTimeRatio 用来精确控制吞吐量
-XX:+UseParallelGC 选择Parallel Scavenge 回收器

二、老年代垃圾回收器

1. Serial Old
与新生代的Serial类似是一个单线程回收器, 不过采用标记-整理算法。

2. Parallel Old
同上,Parallel Scavenge 老年版本, 采用标记-整理算法
-XX:+UseParallelOldGC 设置Parallel Old回收器

3. CMS
CMS 回收器的用户线程等待时间很短
CMS 流程可大致分为四步:

  1. 初始标记: 标记 GC Root 直接关联对象。 耗时短,但仍会叫停其他线程。
  2. 并发标记:并发的根可达分析, 找出垃圾。耗时较长。
  3. 重新标记:为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。多线程,耗时短,但仍会叫停其他线程
  4. 并发清除: 并发使用标记-清除算法清除被标记为垃圾的对象。耗时较长。

因使用标记-清除算法 (减少碎片整理开销),所以会产生内存碎片
-XX:UserCMSCompactAtFullCollection 开关CMS碎片整理 (默认开启)
对CPU资源敏感,随CPU数量减少, 吞吐量减少
-XX:+UserConMarkSweepGC 选择CMS回收器

Java JVM的学习-04 GC垃圾回收 (下)

三、G1回收器

作用于整个堆, 将堆分为若干个大小相等的区域,JVM启动时会根据堆内存自动设置区域大小
每个区域都有一个 Remembered Set 来记录该区域数据与其他区域数据的引用关系, 从而避免根可达分析的时候扫描全部区域
-XX:+UseG1GC 选择G1回收器,JDK9 默认开启

与CMS类似, G1流程可分为以下四个步骤:

  1. 初始标记: 标记 GC Root 直接关联对象。 耗时短,但仍会叫停其他线程。
  2. 并发标记: 并发的根可达分析, 找出垃圾。耗时较长。
  3. 最终标记: 为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录。多线程,耗时短,但仍会叫停其他线程。
  4. 筛选回收: 对各个区域的回收价值成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。并发执行。

四、JVM参数总结

参数 用途
-XX:+UserSerialGC 选择Serial垃圾回收器
-XX:ParallelGCThreads 设置线程数目
-XX:+UseParNewGC 选择ParNew 回收器
-XX:MaxGCPauseMillis 用来控制回收尽可能在多长时间内完成
-XX:GCTimeRatio 用来精确控制吞吐量
-XX:+UseParallelGC 选择Parallel Scavenge 回收器
-XX:+UseParallelOldGC 设置Parallel Old回收器
-XX:UserCMSCompactAtFullCollection 开关CMS碎片整理 (默认开启)
-XX:+UserConMarkSweepGC 选择CMS回收器
-XX:+UseG1GC 选择G1回收器,JDK9 默认开启

如有错误,恳请纠正