30 借HSDB来探索HotSpot VM的运行时数据
Posted 蓝风9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了30 借HSDB来探索HotSpot VM的运行时数据相关的知识,希望对你有一定的参考价值。
前言
呵呵 R大的 经典文章 : 借HSDB来探索HotSpot VM的运行时数据
也来 动手实际过一次
另外就是 文章中提到的 根据 Method 查看方法的字节码信息, 这部分也还是挺有趣的, 我应该是 之前整理在 文档上面了的吧, 多久整理一下
测试用例
package com.hx.test03;
/**
* HSDBInspectClass
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2020-02-01 16:30
*/
public class Test16HSDBInspectClass
// static instanceClass & instanceClass
private static InstanceClass staticInstance = new InstanceClass("staticInstance");
private InstanceClass instance = new InstanceClass("instance");
// 三个 Test16HSDBInspectClass$InstanceClass 实例
// 0x000000079591fd38 Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass InstanceKlass for com/hx/test03/Test16HSDBInspectClass$InstanceClass
// 0x000000079591fdb0 Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass InstanceKlass for com/hx/test03/Test16HSDBInspectClass$InstanceClass
// 0x000000079591fdf8 Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass InstanceKlass for com/hx/test03/Test16HSDBInspectClass$InstanceClass
// Test16HSDBInspectClass
// hsdb> revptrs 0x000000079591fd38
// Computing reverse pointers...
// Done.
//null
// Oop for java/lang/Class @ 0x00000007959170d0
// hsdb> revptrs 0x000000079591fdb0
// Oop for com/hx/test03/Test16HSDBInspectClass @ 0x000000079591fda0
// hsdb> revptrs 0x000000079591fdf8
// null
// null
// hsdb>
// 可以找到 静态变量 和 局部变量, revptrs 找不到 栈帧上面这一个
// 但是可以从 main 方法的栈帧信息里面看到对应的 引用
// hsdb> mem 0x000070000225f908
// 0x000070000225f908: 0x000000079591fdf8
// 三个实例的三个引用, 一个在 instanceKlass 的 java_mirror 里面, 另外一个在新建的实例 thisInstance 里面, 一个在 栈帧上面
public static void main(String[] args)
foo();
// local instanceClass
public static void foo()
Test16HSDBInspectClass thisInstance = new Test16HSDBInspectClass();
InstanceClass localInstance = new InstanceClass("localInstance");
System.out.println(" break point ");
/**
* InstanceClass
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2020-02-01 16:33
*/
private static class InstanceClass
private String str;
public InstanceClass(String str)
this.str = str;
在 foo 方法里面 下图的地方打上一个断点
基于 HSDB 的可视化调试
jps 查看当前进程 pid
启动 hsdb, 连接到 当前进程
Tool >> Object Histogram 查看 Test16HSDBInspectClass$InstanceClass 的信息, 可以发现 三个实例, 我们依次看下 这三个实例
第一个是 Test16HSDBInspectClass.staticInstance, 被在 Test16HSDBInspectClass.class 对应的 oop 引用
第二个是被一个 Test16HSDBInspectClass 实例引用, 这个 Test16HSDBInspectClass 实例被 main线程 栈上的引用 所引用
第三个是被 main线程 栈上的引用 所引用
基于 HSDB 命令行的调试
再来通过 revptrs 来看下 引用这三个 实例的情况呢
revptrs 0x00000007bf07cba0
null
Oop for java/lang/Class @ 0x00000007bf073b58
hsdb> inspect 0x00000007bf073b58
instance of Oop for java/lang/Class @ 0x00000007bf073b58 @ 0x00000007bf073b58 (size = 112)
<<Reverse pointers>>:
staticInstance: Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass @ 0x00000007bf07cba0 Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass @ 0x00000007bf07cba0
hsdb> revptrs 0x00000007bf07cc18
Oop for com/hx/test03/Test16HSDBInspectClass @ 0x00000007bf07cc08
hsdb> inspect 0x00000007bf07cc08
instance of Oop for com/hx/test03/Test16HSDBInspectClass @ 0x00000007bf07cc08 @ 0x00000007bf07cc08 (size = 16)
<<Reverse pointers>>:
_mark: 1
_metadata._compressed_klass: InstanceKlass for com/hx/test03/Test16HSDBInspectClass
instance: Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass @ 0x00000007bf07cc18 Oop for com/hx/test03/Test16HSDBInspectClass$InstanceClass @ 0x00000007bf07cc18
hsdb> revptrs 0x00000007bf07cc60
null
null
hsdb>
在 main线程 栈中的这个 Test16HSDBInspectClass$InstanceClass 实例, revptrs 扫描不到对应的引用, 呵呵 R大 似乎是说明了一下 原因吧
不过 好在至少我们有一个完善的方法 能够找到 引用这个实例 的引用
栈帧信息
从 hsdb 上面截取栈帧信息如下图
我们详细的拆分一下 main, foo 方法的栈帧的相关信息 如下
0x00007000070d28b8 0x00007000070d28b8 : expression bottom
0x00007000070d28c0 0x0000000119ce507a : byte code pointer
0x00007000070d28c8 0x00007000070d2910 : pointer to locals
0x00007000070d28d0 0x0000000119ce51d0 : constants pool cache
0x00007000070d28d8 0x0000000000000000 : method data oop
0x00007000070d28e0 0x0000000119ce50a8 : method oop
0x00007000070d28e8 0x0000000000000000 : last java stack pointer
0x00007000070d28f0 0x00007000070d2918 : old stack pointer
0x00007000070d28f8 0x00007000070d2958 : old frame pointer
0x00007000070d2900 0x000000010a8dd35d : return address[entry_point's address]
0x00007000070d2908 0x00000007bf07cc60 : localInstance
0x00007000070d2910 0x00000007bf07cc08 : thisInstance
-------------------------------------- foo -------------------------------------------
0x00007000070d2918 0x00007000070d2918 : expression bottom
0x00007000070d2920 0x0000000119ce4fc8 : byte code pointer
0x00007000070d2928 0x00007000070d2968 : pointer to locals
0x00007000070d2930 0x0000000119ce51d0 : constants pool cache
0x00007000070d2938 0x0000000000000000 : method data oop
0x00007000070d2940 0x0000000119ce4fe0 : method oop
0x00007000070d2948 0x00007000070d2918 : last java stack pointer
0x00007000070d2950 0x00007000070d2968 : old stack pointer
0x00007000070d2958 0x00007000070d29d0 : old frame pointer
0x00007000070d2960 0x000000010a8d57a7 : return address[entry_point's address]
0x00007000070d2968 0x00000007bf07cbf8 : args
-------------------------------------- main -------------------------------------------
这里可以 清晰的 看到 第三个 Test16HSDBInspectClass$InstanceClass 的引用
完
参考
以上是关于30 借HSDB来探索HotSpot VM的运行时数据的主要内容,如果未能解决你的问题,请参考以下文章