使用JDK的ServiceAbility获得特定的对象

遇到这样一个问题: Java程序中有很多个HashSet. 想找到其元素数目不正常的HashSet的实例. 

当然这个可以用各种工具来做(比如JProfiler等等).

这里用的是JDK自带的ServiceAbility Agent.

具体介绍可以参见

http://rednaxelafx.iteye.com/blog/1847971


首先写个简单的测试程序:


   HashSet s = new HashSet<>();
        for (int i=0; i<100; i++) {
            s.add(i);
        }
        Thread.sleep(100000000);

运行, 使用JPS找到java进程的pid, 然后进入SA的GUI界面:


java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB


然后,进入Tools - Find Object by Query, 输入查询语句

select a from java.util.HashSet a

和SQL很像吧.


这时列出了JDK中当前的所有HashSet的实例的地址. 随便点一个, 查看其内容:


正好就是size = 100的. 然后, 点开其中的tables, 就可以看到key是什么了.

至于为什么属性的顺序是map -> table, 原因就是HashSet其实是个HashMap来实现的.



OK, 那么问题来了: 在真正的产品中, 不可能像这个小测试程序一样, 只有这么几个HashSet. 那么, 如何找到目标HashSet呢?

有两种方法: 

1. 上面的Find Object by Query, 是可以些where条件的, 但是我没有试验出来

2. 使用下面介绍的方法,就是使用Serviceability Agent的JS命令行工具.

在SA的JS命令行工具中, 提供了各种预定义的JS封装的工具类和工具函数, 可以查询JDK内部的各种信息. 感兴趣的可以查看sa-jdi.jar中的sun\jvm\hotspot\utilities\soql\sa.js


首先运行JS工具,连接到Java进程.这里同样用到了pid

C:\jdk8>java -cp .;./lib/sa-jdi.jar sun.jvm.hotspot.tools.soql.JSDB 7540
Attaching to process ID 7540, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.121-b13
jsdb>


然后编辑如下的.js脚本:

print("loaded");
var oh = sa.vm.getObjectHeap();
var kls = findInstanceKlass("java.util.HashSet");
print("kls = " + kls);

forEachOopOfKlass(function(a){
	 // print(a.getHandle());
	 var o = object(addr2str(a.handle));
	 print("Size = " + o.map.size);
	 if (o.map.size >= 100) {
		 print("A set with at least 100 objs", a.handle);
	 }
}, kls, false)


为了方便, 可以在编辑器中编辑, 然后在jsdb中load这个脚本,比如

jsdb> load("c:\\dev\\a.js");


OK, 其实也比较简单. 首先找到类的定义的地址, 然后根据这个地址for each每个类的实例.

对于每个类的实例, 回调处理函数function(a) . 在这个回调函数中, 参数a就是每个实例的表示对象.

a.handle, 就是JDK内部a的地址 (和上面截图中SOQL查询出来的地址一致). 

关键在于

var o = object(addr2str(a.handle));
这一行. 

这一行根据sa.js内置的函数,将地址转换成字符串, 最后通过函数object, 得到具体的类的实例.

最后根据o.map.size >= 100, 就可以打印出来要查找的地址了.


最后, 得到查找的地址之后,可以在SA GUI工具的Tools - Inspect 中直接观察这个地址, 和之前在GUI工具中几个地址一个一个试验, 结果是一致的.

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

lff0305

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值