JVM学习-垃圾收集器
Posted 智公博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM学习-垃圾收集器相关的知识,希望对你有一定的参考价值。
虚拟机有许多的垃圾收集器可以选择,这里简单的记录分享下每个收集器的特点
一、Serial
- 历史最久,曾经是新生代唯一选择
- 单线程,进行时暂停所有用户线程-Stop The World
- Client模式下默认新生代收集器
- 单个线程更加高效简单,没有线程交互开销,一般client应用内存使用不大,停顿时间很短
二、ParNew
- Serial的多线程版本,控制参数、收集算法、Stop The World、对象分配策略、回收策略相同
- 新生代收集器
- 除了Serial已外,只有ParNew可以与CMS配合使用
- 单CPU环境下,性能差于Serial
- 默认下GC线程数与CPU数相同,可配置(-XX: ParallelGCThreads)
三、Parallel Scavenge
- 新生代收集器,采用复制算法
- 并行多线程收集
- 目标不是缩短停顿时间,而是达到可控制的吞吐量:CPU运行用户线程时间与CPU总消耗时间比
- 为了更高效率利用CPU时间
- 两个参数控制吞吐量:最大停顿时间:-XX:MaxGCPauseMillis(>0),直接吞吐量大小:-XX:GCTimeRatio(0~100)
- 尽可能保证停顿时间不超过设置值,
- 短停顿时间以牺牲吞吐量和新生代空闲换取,GC更频繁,吞吐量下降
- GCTimeRatio 吞吐量倒数,默认值99,即最大1% GC时间
- 吞吐量优先
- 自动化开关参数:-XX:+UseAdaptiveSizePolicy,不需手动设置新生代大小(-Xmn)、Eden与Survivor区比例(-XX:SurvivorRatio)、晋升老年代年龄(-XX:PretenureSizeThreadhold),虚拟机GC自适应调节策略:动态调整这些参数提供最适合的停顿时间或最大吞吐量
- 同是多线程并行,自适应调节是与ParNew最大的区别
四、Serial Old
- Serial的老年代版本
- 单线程
- 标记-整理 算法
- 主要用于Client模式
五、Parallel Old
- Parallel Scavenge 老年代版本
- 并行多线程
- 标记-整理 算法
- 在此收集器发布前,Parallel Scavenge 只能与Serial Old配置使用,二Serial Old在服务端应用性能较差
- 与Parallel Scavenge 配合,吞吐量优先
六、CMS
- Concurrent Mark Sweep,并发低停顿
- 以最短停顿时间为目标
- 标记-清除 算法
- 收集四个阶段:初始标记、并发标记、重新标记、并发清除
- 初始标记:Stop The World,快速标记GC Roots直接关联对象
- 并发标记:并发可达性分析
- 重新标记,Stop The World,修正并发阶段对象引用变动导致的变更
- 最耗时的并发标记、并发清除可以与用户线程一起工作
- 对CPU资源敏感,多线程并发程序通常都是这样,当CPU数少,或CPU资源紧张,性能下降
- 无法处理浮动垃圾,可能出现Concurrent Mode Failure 导致另一次Full GC;
- 浮动垃圾(Floating Garbage):并发清理阶段用户线程还在运行,这个阶段新产生的垃圾不会在该次GC回收,因为已经过了标记阶段;
- 不可在老年代几乎用完才启动GC,必须保留较大一部分空间,用于GC中程序继续运行所需,默认68%
- 通过-XX:CMSInitiatingOccupancyFraction控制这个百分比,设置过高会导致“Concurrent Mode Failure”,过低又导致频繁GC
- CMS GC期间,出现内存不出会出现“Concurrent Mode Failure”失败,虚拟机将会启动后背方案,保证内存分配:临时启动Serial Old 重新一次老年代GC,导致长停顿
- 标记-清除 算法导致内存碎片,大对象分配难,导致频繁GC,运行控制Full GC 时开启合并整理,但是会导致停顿时间加长
七、G1(Garbage-First)
- JDK1.7 最新,面向服务端应用
- 并发、并行:充分利用多CPU
- 分代收集,可管理整个堆,包括新生代和老年代
- 标记-整理 、复制 算法,GC不产生碎片
- 低停顿,可预测停顿时间模式
- 内存分区域管理(保留新生代和老年代概念)
- 分区域进行GC,避免全区域GC,高回收价值区域(单位时间内回收更多的内存空间)优先回收,可控制停顿时间
以上是关于JVM学习-垃圾收集器的主要内容,如果未能解决你的问题,请参考以下文章