开发中当技术遇到瓶颈的时候,就需要通过调整JVM来实现技术的进一步优化,面对JVM的性能优化,我自己学习并整理了些知识点。后面会逐渐补充里面的具体细节
常见问题
-
CPU Load过高导致系统不可用或tps急剧降低
-
YoungGC次数频繁
-
FullGC次数频繁
-
FullGC时间长
-
PermSpace GC次数频繁
-
内存泄漏、内存溢出
调优参考数据
-
系统运行日志
-
异常堆栈
-
GC日志
-
线程快照(threaddump/javacore文件)
-
堆转储快照(heapdump/hprof文件)
调优工具
-
jdk命令行工具
-
jps查看系统内所有HotSpot进程
-l:输出主类全名,如果执行的是jar包则输出包名 -v:输出虚拟机启动参数 -m:输出启动时传给main方法的参数
-
jinfo显示虚拟机配置信息
-
jstat收集虚拟机运行数据
每250毫秒查询一次gc情况,查询20次: jstat -gc 22579 250 20
-
jmap生成指定进程堆转储快照(heapdump文件)
生成dump文件: jmap -dump:format=b file=/data/dumpfile.bin 22579 查看堆详细信息(回收器、参数、分代): jmap -heap 22579 查看每个类的实例数量、实例总容量: jmap -histo 22579
-
jhat分析heapdump文件
分析堆转储快照: jhat dumpfile.dmp 启动微型http服务器,生成dump分析结果后可以通过浏览器查看,一般不推荐使用, 建议拷贝到其他空闲机器分析,比较耗资源
-
jstack显示虚拟机线程快照
-
-
可视化工具
-
jconsole和jvisualvm查看内存回收情况
-
BTrace跟踪调试方法
-
jprofiler监控每个类的内存占用
-
MAT工具分析内存占用
-
优化方案
-
JVM配置
-
-Xms和-Xmx的值设置成相等
-
新生代尽量设置大一些
-
-
实现层面
-
避免创建过大的对象及数组
-
避免同时加载大量数据
-
集合中的对象用完后及时清空
-
在合适场景使用软引用、弱引用
-
尽量避免长时间等待外部资源(数据库、网络、设备资源等)
-
设置合理的线程数
-