JVM垃圾收集调优1.0
1、指标
- 最大暂停时间**(-XX:MaxGCPauseMillis=)**优先级低(推荐小堆)(交互式场景优先考虑)
- 暂停用户线程执行垃圾扫描->回收整个过程的时间,多次GC取最大一次暂停时间。
- 通过-XX:MaxGCPauseMillis=单位毫秒,来指定垃圾回收最大暂停时间。
- 垃圾收集器通常会在满足吞吐量指标情况下来保证最大暂停时间指标。某些情况下是无法达到最大暂停时间的指标。
- 吞吐量(-XX:GCTimeRatio=)优先级高(推荐大堆)(Web场景优先考虑)
- 根据垃圾收集时间和垃圾收集之外所花费的时间(应用程序时间)来衡量。可以由参数控制:-XX:GCTimeRatio=。
- 垃圾收集收集时间与应用时间比率为1/(1+nnn)。
- 例如:设置-XX:GCTimeRatio=19,1/(1+19)=0.05。则代表垃圾收集时间占应用程序执行的5%或1/20,如果应用程序执行100秒,则垃圾收集占用5秒。
- 垃圾收集的时间是新生代和老年代收集的总时间。如果吞吐量指标无法满足,则会增加各个代的大小来减少垃圾回收频率,尽可能的满足指标。
如果某个时间点以上两个指标都可以被满足。并且减少堆的大小进行缩减后同样可以进行满足的话,那么JVM会缩减内存的大小。有助于内存使用效率提高。如果后续无法满足该指标,则垃圾收集器会重新调整策略(堆大小)来优先满足吞吐量指标。
调优总结:尽可能不要设置最大堆大小。JVM可以通过吞吐量指标来动态增加堆内存。如果吞吐量目标可以满足,则开始考虑最大暂停时间。系统平稳情况下,最大暂停时间需要堆小一点而吞吐量则需要大堆减少垃圾收集时间。两者冲突。jvm会尝试都满足对方。
2、弱代假说
- 对象在年轻时死亡占比可以达到80%。
- 优化内存,采用分代管理(内存池保存不同年龄的对象)
- step:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/generations.html
3、垃圾收集器分类
-
串行垃圾收集器(
-XX:+UseSerialGC
)- 适用于小型数据集的场景
- 默认参数适配大多数场景
-
并行垃圾收集器(
-XX:+UseParallelGC
)(吞吐量垃圾收集器)(-XX:+UseConcMarkSweepGC
,-XX:+UseG1GC
)- 适用于中型至大型数据集的场景
-
内存分代
- Young(新生代 50%)
- Eden(80%)
- Survivor0 (10%)
- Survivor1(10%)
- Tenured(老年代 50%)
- -XX:NewRatio 控制新生代和老年代比例
- Young(新生代 50%)
-
GC日志
-
-Xloggc:/Users/ydjiang/Projects/logs/hfzafk-gc/20240412gcv2.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -verbose:gc
-
-
影响性能调优因素
- 可用空间:
- 如果GC暂停时间过长,则建议缩小堆的大小
- 建议-Xmx和-Xms设置为相同的值,来提高可预测性。但是如果设置出问题,JVM无法补偿。
- 一般来说,建议随着处理器增加而增加内存分配,因为分配可以并行化。
- 年轻代大小
- 年轻代越大,发生YoungGC频率越小,但是随之老年代空间占比就会缩减,将会增加老年代GC频率,最佳分配取决于对应应用程序中分配的对象的生命周期。
- 年轻代大小参数设置:-XX:NewRatio=3。意味着年轻代和老年代比例为1:3,相当于新生代占用整堆的1/4的空间。
- NewSize。MaxNewSize设置为相同大小也可以限制新生代大小。粒度比NewRatio更细。
- 幸存者空间大小设置参数(不重要):-XX:SurvivorRatio=6。
- 如果幸存者空间太小,则复制存活对象可能溢出到老年代。如果过大,那么会造成空间浪费。每次垃圾回收时,都会检查对象被复制到幸存者空间的次数,如果到达阈值(15)则会被转移到老年代。
- -XX:+PrintTenuringDistribution;显示此阈值和新生代中对象的年龄。
- 可用空间: