Sun HotSpot垃圾回收器
概览
新生代和老年代用到的一些垃圾回收器
永久代
当永久代和老年代触发 GC 时,除CMS均会触发 Full GC
- 首先按照新生代配置的GC方式进行 Minor GC;
- 再按照老年代配置的GC方式对老年代和永久代进行GC;
- 若 JVM 估计 Minor GC后可能会发生晋升失败,则直接采用老年代配置的GC方式对新生代,老年代进行GC
一些术语
串行 ( Serial ) vs 并行 ( Parallel )
在单核CPU上并行可能更慢
STW ( Stop-the-world ) vs 并发 ( Concurrent )
- STW : 暂停整个应用,时间可能会很长;
- 并发 ( Concurrent ) : 更加复杂,GC可能会抢占应用的CPU;
新生代可用GC
均使用复制算法,原理上是一致的:
- 拷贝 eden 和 from 中的存活对象到 to 中;
- 部分对象由于某些原因晋升到 old 中;
- 清空 eden, from, from 和 to 交换身份直到下一次GC发生
分配对象时,eden 空间不足时触发
Serial Copying
特性
Serial, Stop-the-world
适用场景
- 单CPU, 新生代小, 对暂停时间要求不高的应用;
- 是 client 级别或32位Windows上的默认选项
对象分配在老年代的情况
- 对象超过 eden space 的大小
- 大对象
晋升规则
- 经历多次 minor gc 仍存活的对象
- to survivor 放不下的(满或剩余空间不够)对象直接晋升
Parallel Scavenge
特性
- Parallel、 Stop-the-world
- 并行线程数默认值:
- CPU核数 <= 8:=CPU核数
- CPU核数 > 8 := (3 + CPU核数 * 5)/8,
- 亦可强制指定线程数 (-XX:ParallelGCThreads=4)
- 会根据 minor GC 的频率、时间等动态调整 eden/s0/s1 的大小,可取消这一特性
- -XX:-UseAdaptiveSizePolicy
适用场景
- 多CPU、对暂停时间要求较短的应用
- 是server级别(2核CPU 2G内存)机器上的默认选择
对象分配在老年代的情况
- 在 TLAB 和 eden 上分配失败,且对象大于eden的一半大小
- PretenureSizeThreshold参数是无效的
晋升规则
- 经历多次minor GC仍存活的对象(规则和参数都比Serial Copying复杂);
- to survivor放不下的(满或剩余空间不够)对象直接晋升
ParNew
特性
- Parallel、Stop-the-world
- 可以认为是Serial Copying的多线程版本,各项特征与之基本一致
- 可以搭配CMS
- 不可搭配Parallel Old
老年代可用GC
Serial MSC
特性
- Serial、Stop-the-world
- 使用算法:Mark-Sweep-Compact
- 由于是单线程,GC造成的暂停时间可能会很长,可使用-XX:+PrintGCApplicationStoppedTime查看暂停时间
适用场景
- 是client级别或32位Windows上的默认选择
Parallel Compacting
特性
- Parallel、Stop-the-world
- 使用算法:Mark-Compact
适用场景
- 多核CPU、对暂停时间较敏感的应用
- 是server级别(2核CPU 2G内存)机器上的默认选择
Concurrent Mark-Sweep(CMS)
特性
- Parallel、Concurrent
- 使用算法:Mark-Sweep
- 缩短GC暂停时间,但相当复杂,增加了GC总时间
- 默认并发线程数=(新生代并行GC线程数 + 3)/4,也可用-XX:ParallelCMSThreads=2来指定
- 对Perm Generation也可启用CMS:-XX:+CMSPermGenSweepingEnabled,-XX:+CMSClassUnloadingEnabled
适用场景
- 暂停时间短,对追求最快响应速度的应用,尤其是互联网应用很适用
组合
支持的组合
两个标准
- 吞吐量=应用运行时间/总时间
- 关注GC总耗时
- 暂停时间
- 关注每次GC造成的应用暂停
组合的选择
- 单CPU或小内存,单机程序(-XX:+UseSerialGC)
- 多CPU,需要最大吞吐量,如后台计算型应用(-XX:+UseParallelGC或者-XX:+UseParallelOldGC)
- 多CPU,追求低停顿时间,需快速响应如互联网应用(-XX:+UseConcMarkSweepGC -XX:+ParNewGC)
自动选择GC方式
- 吞吐量优先
- -XX:GCTimeRatio=n
- 暂停时间优先
- -XX:MaxGCPauseMillis=n
- 一般不使用
触发GC-young GC
- eden 区的内存不够时,就会触发young GC
- 对象分配内存
- 为TLAB分配内存
Ps:young GC中有部分存活对象会晋升到old gen,所以young GC后old gen的占用量通常会有所升高
触发GC-full GC
- old gen 空间不足
- 统计得到 young GC 晋升到 old gen的对象总和大于old gen 剩余空间
- young GC出现 promotion failure
- 执行 System.gc()、jmap -histo:live
- perm gen 空间不足