七种垃圾回收器类型
GC 的约定参数
- DefNew--Default New Generation
- Tenured--Serial Old
- ParNew--Parallel New Generation
- PSYoungGen--Parallel Scavenge
- ParOldGen--Parallel Old Generation
适用范围: 只需要掌握 Server 模式, Client 模式基本不会用.
操作系统: 32 位 Windows 不论硬件如何默认使用 Client 模式. 32 位其他 OS,2G 内存同时 2 个 CPU 以上用 Server 模式, 低于该配置是 Client 模式. 64 位只有 Server 模式.
七大垃圾收集器
串行 GC:Serial 收集器(1:1)
串行收集器是最古老的, 最稳定, 效率高的收集器, 只使用一个线程去回收但其进行垃圾回收过程中可能会产生较长的停顿. 虽然在收集垃圾的过程中需要暂停其他的工作线程, 但是简单高效, 对于单 CPU 环境来说, 没有线程交互的开销可以获得最高的单线程垃圾收集效率, 因此 Serial 垃圾回收器依然是 Java 虚拟机运行在 Client 模式下默认的新生代垃圾回收器.
开启串行收集器的 JVM 参数是 - XX:+UseSerialGC.
开启后会使用: Serial(Young 区)+ Serial Old(Old 区)的收集器组合. 表示新生代, 老年代都会使用串行回收收集器, 新生代用复制算法, 老年代用标记整理算法.
显式激活垃圾回收器:
并行 GC:ParNew(N:1)
使用多线程进行垃圾回收, 在垃圾回收时, 会暂停所有其他工作线程, 直到 GC 结束.
ParNew 时 Serial 收集器新生代的并行多线程版本, 最常见的应用场景是配合老年代 CMS GC 工作, 其余行为和 Seria 收集器完全一样, ParNew 垃圾收集器在垃圾收集过程中同样要暂停所有其他的工作线程. 它是很多 JVM 运行在 Server 模式下新生代的默认垃圾收集器.
开启串行收集器的 JVM 参数是 - XX:+UseParNewGC.
启用 ParNew 收集器, 只影响新生代的收集 (新生代 GC 频繁), 不影响老年代. 开启参数后, 会使用 ParNew(Young 区)+Serial(Old 区) 的收集器组合. 新生代使用复制算法, 老年代使用标记整理算法.
ParNew+Tenured(Serial Old)不再推荐使用:
并行回收: Parallel Scavenge(N:N)
Parallel Scavenge 收集器类似 ParNew, 也是一个新生代垃圾收集器, 使用复制算法, 也是一个并行的多线程的垃圾收集器, 俗称吞吐量优先收集器. 相当于是串行收集器在新生代和老年代的并行化.
它重点关注可控制吞吐量, 高吞吐量意味着高效利用 CPU 时间, 它多用于在后台运算而不需要太多交互的任务.[吞吐量 = 用户代码运行时间 /(用户代码运行时间 + 垃圾回收时间)]
自适应调节策略也是 Parallel Scavenge 收集器与 ParNew 收集器的一个重要区别. 自适应调节策略就是 JVM 会根据当前系统的运行情况看收集性能监控信息, 动态调整这些参数以提供最合适的停顿时间 (-XX: MaxGCPauseMills) 或最大吞吐量.
常用的 JVM 参数:-XX:+UseParallelGC 或者 +UseParallelOldGC(二者可以互相激活), 使用 Parallel Scavenge 收集器. 开启参数后, 新生代用复制算法, 老年代用复制标记整理算法.
参数 - XX:+ParallelGCThread = K 表示启动 K 个 GC 线程[CPU> 8 K = 5 或 8 CPU < 8 K = 实际个数]
Parallel Old 收集器
Parallel Old 收集器是 Parallel Scavenge 收集器的老年代版本, 使用多线程的标记整理算法, 在 JDK1.6 开始提供.
JDK1.6 之前, 新生代使用 Parallel Scavenge 收集器只能搭配老年代 Serial Old 收集器, 只能保证新生代的吞吐量优先, 无法保证整体的吞吐量. 在 JDK1.6 之前, 是 Parallel Scavenge+Serial Old.
Parallel Old 是为了老年代同样提供吞吐量优先的垃圾收集器, 如果系统对吞吐量要求较高, JDK1.8 后优先考虑新生代 Parallel Scavenge 和老年代 Parallel Old 的搭配策列. 在 JDK1.8 及之后, 是 Parallel Scavenge+Parallel Old.
JVM 常用参数:-XX:+UseParallelOldGC 使用 Parallel Old 收集器. 和上一个 part 的截图是一致的, UseParallelGC 和 UseParallelOldGC 可以互相激活.
并发标记清除 GC(CMS)
CMS 收集器是一个以获取最短回收停顿时间为目标的收集器. 适合应用在互联网站或 BS 系统的服务器上, 因为这类场景重视服务器的响应速度, 希望系统的停顿时间尽可能短. CMS 适合堆内存大, CPU 核数多的服务器端应用, 也是 G1 出现之前大型应用的首选收集器.
CMS 的优势是并发收集停顿少, 并发是指与用户线程一起执行.
开启收集器的 JVM 参数:-XX:+UseConcMarkSweepGC 开启后会自动开启 -XX:+UseParNewGC
并发标记清除收集器的组合: ParNew + CMS + Serial Old(作为 CMS 出错的后备收集器, 增强健壮性)
CMS 内存回收一共有 4 个过程:
初始标记: 只有标记一下 GC Roots 能直接关联的对象, 速度很快, 仍然需要暂停所有的工作线程.
并发标记: 进行 GC Roots 跟踪的过程, 和用户线程一起工作, 不需要暂停工作线程, 主要标记过程, 标记全部对象.
重新标记: 修正在并发标记期间, 因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录, 仍然需要暂停所有的工作线程. 由于并发标记时, 用户线程依然运行, 因此在正式清理前再做修正.
并发清除: 清除 GC Roots 不可达对象, 和用户线程一起工作, 不需要暂停工作线程. 基于标记结果, 直接清理对象. 由于耗时最长的并发标记和并发清除过程中, 垃圾收集线程可以和用户线程一起并发工作. 所以总体上说 CMS 收集器的内存回收和用户线程是并发执行的(初始标记和重新标记虽然要暂停, 但是用时很短).
优点: 并发收集, 停顿次数少.
缺点: 对 CPU 的压力大, CMS 在收集和应用线程会同时增加对堆内存的占用, 也就是 i 说 CMS 必须在老年代堆内存用完之前完成 GC, 否则 CMS 会回收失败, 将触发担保机制, Serial Old 会以 STW(Stop The World, 暂停所有工作线程)的方式进行依次 GC, 从而造成较大的停顿时间. 而且采用标记清除算法会产生内存碎片.
Serial Old 收集器
Serial Old 收集器是 Serial 垃圾收集器老年代版本, 同样是单线程的收集器, 使用标记整理算法.
主要运行在 Client 默认的 JVM 老年代垃圾回收器.
在 Server 模式下, 主要有两个用途:
在 JDK1.5 之前与新生代 Parallel Scavenge 收集器搭配使用.(Parallel Scavenge+Serial Old)
作为老年代版中使用 CMS 收集器的后备垃圾回收方案.
G1 垃圾回收器
内容较多, 见[JVM] 垃圾回收器总结(3)
来源: https://www.cnblogs.com/xdcat/p/13040725.html