一,jvisualVM介绍
jvisualVM是一款jdk自带的图像化jvm性能监控工具,可以:
- 实时监控堆内存的变化情况
- 一键生成堆转储文件并解析并图形化展示
- dump线程信息(相当于jstack)
- 堆内存profiler(相当于jmap -histo展示堆内对象直方图)
- CPU、内存、线程、已加载的类统计
二,实时监控堆内存使用情况
很棒的一点是,这个图是动态变化的,可以动态的看见堆内存各区域的动态变化:
- eden区内存占用逐渐增多
- eden区垃圾回收
- eden区对象复制到幸存区
- 幸存区对象复制到老年代
- full gc
- ygc的统计数据
- fgc的统计数据
使用案例:
生产环境服务器处理业务请求变慢,通过jvisualVM发现ygc的次数非常频繁,没发生fgc,老年代的空间非常充足,以上现象说明eden区的空间小,但是这台机器的内存是32G,不至于缺乏内存,从jvisualVM上看,可用的eden区内存高达3G。那为什么会频繁的ygc呢?
仔细研究发现,虽然eden区的可用内存也即最大可分配内存高达3G,但实际分配给eden区的内存只有150M,难怪ygc那么频繁。
那为什么只分配给eden区150M内存呢,继续观察发现old区的分配内存也没有想象中的多,但是old区在不断的动态调整,不断扩大,eden区的实际分配内存基本没有变化。
心里大致有底了,检查了下jvm参数,发现没有配置-Xms、-Xmx,在没有明确指定堆内存的大小的情况下,jvm会根据应用所需要的最小堆内存进行内存规划,导致了eden区过小。
定位到了这个问题,就知道该怎么办了,显式配置-Xms8g、-Xmx8g,重启应用,ygc明显减少,应用吞吐量大幅增加,一次成功的jvm优化。
这里需要清楚jvisualVM的visual gc界面的使用,visual gc是jvisualVM的插件,要先安装,安装极其简单,通过jvisualVM即可快速完成。
visual gc界面详解:
关键要理解eden可用大小和实际分配大小,如果不通过-Xms、-Xmx明确指定堆空间大小的话,eden可用大小和实际分配大小可能会有很大差距,导致eden区频繁发生ygc。
三, 一键生成堆转储文件并解析并图形化展示
1,生成dump文件
2,自带解析并可视化
可以通过实例数找到大对象和大集合对象 ,以及通过“与另一个堆转储进行比较”确定不同时间点上对象在堆内存的变化情况,结合实际情况根据这些线索进一步确定问题所在。
MAT是更强大的dump文件分析工具,如果说有必须要掌握的图形化jvm监控工具的话,jvisualVM和MAT是唯二两款。
后面再分析MAT的使用。
四,dump线程信息(相当于jstack)
1,生成线程信息
2,查看生成的线程相关信息
查看线程状态及各状态持续时间。
可惜的是,不能搜索,生成环境几十上百个线程,不能搜索就代表着鸡肋。
案例:定位C3P0连接池满导致应用阻塞,响应缓慢
thread2一直被阻塞,直接原因是线程池连接数全部被占用,连接池被用完有如下几个可能:
- 连接池数设置过少
- sql执行慢,导致连接长时间被占用
- 连接使用完成后未被释放
- 数据库异常,如锁表
解决方案:
1,加大连接池数量;
2,修改代码,使用完连接后要关闭连接;
3,优化sql,提升sql执行性能;