HSDB的使用

jdk中额外提供了很多工具,其中HSDB就是一款可用于调试jvm运行时数据的图形化工具,存在于jdk目录lib文件夹下的sa-jdi.jar中

启动方式

如果出现加载sawindbg.dll失败,那么可以去 jdk目录下的jre\bin文件夹下找到该文件复制到jre目录

 编写测试用例

该测试代码为深入理解Java虚拟机书中的例子

package com.jvm;

public class HsdbTest {
    static class Test {
        static ObjectHolder staticObj = new ObjectHolder();
        ObjectHolder instanceObj = new ObjectHolder();

        void foo() {
            ObjectHolder localObj = new ObjectHolder();
            System.out.println("done");//为了不让程序终止,在这里加入断点
        }
    }

    private static class ObjectHolder {

    }

    public static void main(String[] args) {
        Test test = new Test();
        test.foo();
    }
}

通过jps找到该程序的id为10028

 

 这里显示的就是新生代(Eden、Survivor From、Survivor To)以及老年代的虚拟内存地址起始范围

接下来打开windows->console窗口,输入命令

scanoops 0x000000076ba00000 0x0000000770400000 com.jvm.HsdbTest$ObjectHolder

由图可以看出,上述代码中staticObj、instanceObj、localObj三个变量的对象实例都存储在堆中

然后点击Tools->Inspector,可以查看对象头和指向对象元数据的指针,包含了Java类型的名字、继承关系、实现接口关系,字段信息、方法信息、运行时常量池的指针、内嵌的虚方法表(vtable)以及接口放发表(itable)

接着根据堆中对象实例地址找出引用它们的指针,使用Tools->Compute Reverse Ptrs或者在console中使用命令revptrs 0x000000076baec540来查看

 然后在java.lang.Class的实例中找到了对该对象的引用

从《Java虚拟机规范》所定义的模型看,所有Class相关的信息都应该存放在方法区中,但具体如何实现却并未规定。JDK7及其以后版本的HotSpot虚拟机选择把静态变量与类型在Java语言一端的映射Class对象存放在一起,存储于Java堆中

而第二个对象实例(instanceObj)就是指向了Test类了

 第三个对象实例(localObj)由于是在方法中,所以是Java栈的栈帧中的局部变量表在引用这个对象实例,而revptrs命令并不支持查找栈上的指针引用,所以返回了null

不过在简单代码中还可以人工来查找,通过下图在该线程的栈内存中找到了有个地方引用了该对象实例内存地址的值

且已经生成了注释,这里引用了来自年轻代的com/jvm/HeadTest$Test对象实例

 

以上就是根据一个类中三个对象的定位来演示HSDB工具的例子

 总结:

        1.HSDB工具的大概使用方法

        2.JDK7之后,静态变量被Class对象引用,且都存放于Java堆中

        3.对象实例存放于堆中

        4.方法中的对象变量存放于虚拟机栈的栈帧中的局部变量表中,通过指针指向Java堆中的对象实例数据(当然这里的引用可能分为句柄引用和指针引用,不过hotspot虚拟机一般采用的是指针引用)

引申:

        JDK9以后,jmap、jstat、jmap等工具都移入到jhsdb中了,不需要再单独使用各自的命令了

        

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值