深入JVM学习之VisualVM 工具分析GC
VisualVM:多合一故障处理工具 VisualVM是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序,并且可以预见在未来一段时间内都是官方主力发展的虚拟机故障处理工具。他除了运行监视,故障处理外,还提供了很多其他方面的功能。如性能分析等
【Java|深入JVM学习之VisualVM 工具分析GC】VisualVM基于NetBeans平台开发,因此它一开始就具备了插件扩展功能的特性,通过插件扩展支持,VisualVM可以做到:
- 显示虚拟机进程以及进程的配置、环境信息(jps、jinfo)
- 监视应用程序的CPU、GC、堆、方法区以及线程的信息(jstat、jstack)
- dump以及分析堆转储快照(jmap、jhat)
- 方法级的程序运行性能分析,找出被调用最多、运行时间最长的方法
- 离线程序快照:收集程序的运行时配置、线程dump、内存dump等信息建立一个快照,可以将快照发送开发者处进行Bug反馈。
- 其他plugins的无限可能性
VisualVM使用演示 运行位置
Visualvm.exe 可以在JDK安装路径bin目录找到,运行即可监视本地Java程序
使用IDEA的同学可以安装VisualVM插件使用更方便.
文章图片
安装完就能看到运行处多了两个图标,点击就能启动VisualVM
文章图片
测试程序
在演示之前我们先准备一段测试程序,后面用Visualvm对这段程序运行情况分析
public class TestJvm {
public static void main(String[] args) {
byte[] allocation1, allocation2, allocation3, allocation4, allocation5;
//为了方便监视,这里休眠一下
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
allocation1 = new byte[4*1024*1024];
allocation2 = new byte[1*1024*1024];
allocation3 = new byte[4*1024*1024];
allocation4 = new byte[4*1024*1024];
allocation4= null;
allocation5 = new byte[4*1024*1024];
}
}
程序运行时参数设置
-XX:+PrintGCDetails 打印GC日志
-Xms20M 初始堆大小
-Xmx20M 最大堆大小
-Xmn10M 新生代堆大小
运行观察日志打印
[GC (Allocation Failure) [PSYoungGen: 8192K->1016K(9216K)] 8192K->1632K(19456K), 0.0040618 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 8342K->1016K(9216K)] 13054K->6684K(19456K), 0.0030396 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 6244K->5086K(9216K)] [ParOldGen: 9764K->6542K(10240K)] 16009K->11628K(19456K), [Metaspace: 9157K->9157K(1058816K)], 0.0413284 secs] [Times: user=0.20 sys=0.00, real=0.04 secs]
[GC (Allocation Failure) [PSYoungGen: 8192K->984K(9216K)] 14734K->7526K(19456K), 0.0021684 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
PSYoungGentotal 9216K, used 1220K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 2% used [0x00000000ff600000,0x00000000ff63b068,0x00000000ffe00000)
from space 1024K, 96% used [0x00000000ffe00000,0x00000000ffef6010,0x00000000fff00000)
tospace 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGentotal 10240K, used 6542K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 63% used [0x00000000fec00000,0x00000000ff263838,0x00000000ff600000)
Metaspaceused 9172K, capacity 9514K, committed 9728K, reserved 1058816K
class spaceused 1090K, capacity 1186K, committed 1280K, reserved 1048576K
控制台能够观察到我们这里发生3次GC和1次Full GC
VisualVM 监视
在监视窗口下,可以看到CPU、堆、线程等使用情况实时监控
文章图片
在Visual GC窗口下,可以看到年轻代和老年代的GC次数和时间使用情况
文章图片
在抽样器点击内存抽样,可以快照实时的内存使用情况,包括实例和字节数,发生内存溢出时,可以通过字节使用情况定位原因
文章图片
分析dump文件
VisualVM 还可以分析堆dump文件
上面的程序我们修改下,让其发生内存溢出,然后dump堆文件
增加参数
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=java.hprof 发生内存溢出时dump堆使用情况
public class TestJvm {
public static void main(String[] args) {
byte[] allocation1, allocation2, allocation3, allocation4, allocation5;
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
allocation1 = new byte[4*1024*1024];
allocation2 = new byte[1*1024*1024];
allocation3 = new byte[4*1024*1024];
allocation4 = new byte[4*1024*1024];
//try {
//Thread.sleep(10000);
//} catch (InterruptedException e) {
//e.printStackTrace();
//}
allocation5 = new byte[3*1024*1024];
}
}
发生内存溢出后,可以在项目的根目录找到我们dump的java.hprof文件
在VisualVM 文件–》装入–》选择堆dump 将java.hprof加载到Visual VM中
在概述窗口可以查看内存溢出的位置
文章图片
在类窗口可以看出发生内存溢出时,堆的使用情况
文章图片
通过上面两个窗口的内容分析,基本能够定位出内存溢出的原因,方便我们调整
VisualVM远程连接 我们上面讲的都是VisualVM监控本地的java进程,更多的场景是我们监视服务器的使用情况,我们可以通过VisualVM远程连接服务器达到监视的目的。
想要监视服务器情况,需要在服务器运行jstatd 守护进程
- 在 $JAVA_HOME/bin 下创建安全策略文件,命名为 jstatd.all.policy,内容如下:
grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;
};
- 运行 jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=xxx.xx.xx.xx (hostname 为你的 IP)
- 在远程处创建远程连接
文章图片
连接成功将就可以监视服务器的运行状况了
文章图片
参考资料:《深入理解Java虚拟机》
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)