狸猫技术窝公众号上的救火队队长的《从О开始带你成为jvm 实战高手》,有非常详细的案
1. Jvm调优
1.1. 最佳实践
@最大堆内存和最小堆内存设置一样大
@设置线程栈大小为512或者甚至256,一般情况下,默认1Mb太大了
@设置大对象大小闸阀,大对象直接在年老代分配,否则可能会频繁造成ygc
@-XX:+UseAdaptiveSizePolicy 该参数开启,让ps垃圾回收器调整最优策略
1.2. 问题定位工具
1.2.1. Jvisual(jconsole升级版)
在jdk的bin目录下能找到。通过工具还可以添加插件。其中包括gc的一个插件,可以查堆各个模块的内存情况,及其动态的回收情况。查看线程情况。
之前就遇到过一个情况,一个同事,在写一个回调方法中,用了线程池,线程池不是静态化的,导致触发一次就会创建一个线程池,导致创建大量线程,我就是通过jvisual轻松拿下的。
1.2.2. Jstack
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码。
第一步,得到服务进程的pid
第二步,top -Hp pid,查询最消耗内存的线程 --》21742
第三步,printf "%x " 21742,得到一个16进制的数,假定为54ee
第四步,jstack 21711 | grep 54ee,可以定位到具体的类的方法
1.2.3. Gc日志
开启gc日志,
通过https://gceasy.io/分析gc日志,得到分析详细的垃圾回收信息,非常详细
1.2.4. 垃圾回收器选择
不同场景运营不用垃圾回收器
Serial,串行,单cpu 下性能极好
Ps垃圾回收器,1.8jdk默认,可以设置最大停顿时间和吞吐量
G1(garbege first)1.9默认,在垃圾回收器中是最前沿的技术之一
1.2.5. 高版本JDK下的gc
ZGC(jdk11)
低延迟的ZGC,不管堆内存多大,都能使得STW时间不会超过10ms;和现有的G1相比,应用吞吐能力的下降不会超过15%
ZGC是一个并发、基于区域(region)、标记压缩算法的GC,只有根结点扫描阶段会发生STW,因此停顿时间不会随着堆内存的增长和存活对象的增长而增长
目前ZGC只能用于64位的linux操作系统下
Shenandoah(雪兰多)
最大的区别在于雪兰多收集器实现了并发疏散环节,引入的Brooks Forwarding Pointer技术使得GC在移动对象时,对象的引用仍然可以访问,这样就降低了延迟,相关团队宣城是使99.9%的暂停小于10ms。
G1可终止的混合垃圾回收(jdk12),主要思路是:把回收集分为必须部分和可选部分,优先处理必须部分。
1.2.6. 其他
Jmap,jstat,其实在gceasy,和jvisual都包含了类似的功能。
参考 https://blog.csdn.net/qq_37475168/article/details/107108462 不通版本jdk
https://my.oschina.net/feichexia/blog/196575 jvm调优实战