JVM总结笔记
整个堆大小 = 新生代大小 + 年老代大小
新生代:Eden+From Survivor+To Survivor
收集器 | 使用的区域 | 采用的算法 | 单/多 | 特点 |
Serial | 新生代 | 复制算法 | 单 | 暂停其他所有的工作线程,影响正常使用体验 |
ParNew | 新生代 | 复制算法 | 多 | 暂停其他所有的工作线程,影响正常使用体验 |
Parallel Scavenge | 新生代 | 复制算法 | 并行、多线程 | 达到一个可控制的吞吐量,通过参数设置 |
CMS | 老年代 | 标志-清除 | 并发 | 获取最短回收停顿时间为目标的收集器 |
Serial Old | 老年代 | 标志-整理 | 单 | Serial Old是Serial收集器的老年代版本 |
Parallel Old | 老年代 | 标记-整理 | 多线程 | Parallel Scavenge收集器的老年代版本 |
G1 | 整堆 | 标记-整理 | 并行、并发,分代收集、空间整合、可预测的停顿 | 面向服务端应用的垃圾收集器 |
表1 收集器汇总
算法汇总
- 标志-清除算法
-
- 步骤:两次标志,回收
- 基于最基础的 可达性分析算法
- 优点:
- 缺点:
- 应用场景:针对老年代的CMS收集器;
-
- 复制算法
-
- 步骤:
- 复制算法
- 优点:简单、高效
- 缺点:浪费内存空间
- 适用场景:新生代,因为新生代存活率低
- 收集器:如Serial收集器、ParNew收集器、Parallel Scavenge收集器、、G1(从局部看);
-
- 标志-整理算法
-
- 步骤:先标志,再整理
- 算法:
- 优点:不会像复制算法,效率随对象存活率升高而变低
- 缺点:效率低
- 适用场景:老年代,因为老年代存活率高
- 收集器:Serial Old收集器、G1
-
- 分代收集算法
-
- 步骤:
- 算法:
- 优点:
- 缺点:
- 适用场景:
- 收集器:
-
JVM常见配置参数
- 堆设置
-Xms:2G 初始堆大小
-Xmx:2G 最大堆大小
-XX:NewSize=1G 设置年轻代大小
-XX:NewRatio=4 新生代:老年代 = 1:4 也就是新生代是总堆的20%
-XX:SurvivorRatio=4 eden是4, s0是1,s1 是1, 4:1:1。Eden区是新生代的80%
- 收集器设置
-XX:+UseSerialGC 采用串行收集器
-XX:+UseParalleGC 采用并行收集器
-XX:+UseParalleOldGC 采用并行老年代收集器
-XX:+UseConcMarkSweepGC 采用并发收集器
三、调优原则:
1、年轻代大小的选择
响应时间优先的应用:尽可能大的年轻代
吞吐量优先的应用:尽可能大的年轻代
- 年老代大小的选择
响应时间优先的应用:小了、大了都不行,综合考虑
吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是,这样可以尽可能回收掉大部分短期对象,减少中期的对象,而年老代尽存放长期存活对象。
因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,他会把相邻的空间进行合并,这样可以分配给较大的对象。但是,当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:
1. -XX:+UseCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。
2. -XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩