基础故障工具
在JDK中,有很多工具可以进行对虚拟机的性能监控,或者是故障处理。
jps:虚拟机进程状况工具
之前在讲多线程的时候也有用到了,在检查死锁问题的时候,使用jps查看是哪个线程。
jstat:虚拟机统计信息工具
jstat可以用于对线程的监控和统计,如图:
对 15192线程查询GC的情况,一共查询20次,每250ms一次。
jinfo:Java配置工具
jinfo可以用于查询和配置Java虚拟机的配置信息,但在Windows平台限制较大,只能使用-flag指令。
jmap:Java内存映像工具
能进行对内存的信息进行快照存储,如图:
让虚拟机生成堆转储快照文件,一个生成的文件名为eclipse.bin ,去进程15192获取。
jhat:虚拟机堆转储快照分析工具
jhat命令可以和jmap搭配使用。如图:
能够分析出这个eclipse文件,看到分析结果。
jstack:Java堆栈跟踪工具
能够追踪到Java堆栈的运行状况,如图:
拿出之前发生过死锁的程序来进行判断,寻找死锁的原因。
可视化故障工具
JDK除了大量的命令行工具之外,也有一些好用的可视化工具去对故障进行处理。
JHSDB:基于服务性代理的调试工具
JHSDB是一款基于服务性代理实现的进程外调试工具。它可以在一个独立的JAVA虚拟机进程里分析其他的HotSpot虚拟机的内部数据。我们这次就是JHSDB分析一下以下代码,看看staticObj、instanceObj、localObj存放在哪里?
1 | /** |
首先通过jps查询进程,再通过Jhsdb打开图形化模式。
打开后如图:
运行到断点处,一共会创建三个ObjectHolder对象的实例。只要是对象实例,就必然会在Java堆中分配。
先点击菜单的Tools-> Heap Parameters
接着在Windows的
scanoops 0x0000020717600000 0x0000020717950000 test$ObjectHolder
注意要使用相应的内存地址,在寻找的时候你也可以看到cmd同时也进行的寻址:
最后我们运行完,可以看到这三行内容:
找出了这三个实例的地址。然后继续使用tools的Inspector,去查找:
发现查找到的正是我们所在的类的内存,接下来要根据堆中对象实例地址找出引用它们的指针。使用如下命令:
那么在根据得到的指针去寻找是否就是对应的对象。
可以看到,正是指向了我们所引用的对象实例,可见这是正确的行为。接下来试试第二个:
再查找:
第三个:
发现第三个居然不行了,直接显示为null,表示查找不到这个指针。看来revptrs命令并不支持查找栈上的指针,但这并不妨碍我们。我们还可以用Java Thread窗口的main线程,点击Stack Memory,手动去寻找栈内存。
如此一来,三个对象都找到了,还追溯到了引用它们的地方。