The Top-Level HotSpot Debugger - HSDB

HSDB: The top-level HotSpot Debugger

  • debugger

    • gdb c,c++ based on ptrace
    • jdb java jdi,jdwp,etc
    • hsdb top-level
  • 源码

    • openjdk/hotspot/agent/***/sun.jvm.hotspot/HSDB.java
  • Usage

    • jps
    • java -cp %JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.HSDB help
  • 通过HSDB来了解String值的真身在哪里

  • 借HSDB来探索HotSpot VM的运行时数据

    • javac -g xxx.java (Generate all debugging info 生成LocalVariableTable等调试信息)
    • -XX:+UseSerialGC -Xmx10m
    • 之前在GreenTeaJUG在杭州的活动演示Serviceability Agent的时候也讲到过这是个非常便于探索HotSpot VM内部实现的API,而HSDB则是在SA基础上包装起来的一个调试器。这次我们就用HSDB来做实验
    • SA的一个限制是它只实现了调试snapshot的功能:要么要让被调试的目标进程完全暂停,要么就调试core dump。
    • 所以我们在用HSDB做实验前,得先让我们的Java程序运行到我们关注的点上才行。
    • JPDA(java platform debugger architecture)
      • jvmti(jvm tool interface)
      • jdwp(java debugger wireless protocol)
      • jdi(java debugger interface)
    • IDE Debugger or jdb
    • jdb
      • jdb -XX:+UseSerialGC -Xmx10m
      • stop in Test.fn
      • run Main
      • next
    • jps
    • java -cp .;%JAVA_HOME%/lib/sa-jdi.jar sun.jvm.hotspot.HSDB
    • 连接上的pid进程显示一些线程
      • Signal Dispatcher Java的attach机制实现
      • Attach Listener Java的attach机制实现
      • Finalizer
      • References Handler 堆外内存 Cleaner对象的clean()方法调用
      • main
        • 查看main线程的栈 Stack Memory
      • hsdb console
        • 用universe命令来查看GC堆的地址范围和使用情况
        • 这里用的是HotSpot VM的serial GC。GC堆由young gen = DefNewGeneration(包括eden和两个survivor space)、
        • old gen = TenuredGeneration和perm gen = PermGen构成。
        • 其中young gen和old gen构成了这种配置下HotSpot VM里的Java堆(Java heap),
        • 而perm gen不属于Java heap的一部分,它存储的主要是元数据或者叫反射信息,主要用于实现JVM规范里的“方法区”概念
      • scanoops
        • scanoops 0x00000000fa400000 0x00000000fc2c0000 Test2
        • scanoops接受两个必选参数和一个可选参数:必选参数是要扫描的地址范围,一个是起始地址一个是结束地址;可选参数用于指定要扫描什么类型的对象实例。实际扫描的时候会扫出指定的类型及其派生类的实例。
        • 左边是对象的起始地址,右边是对象的实际类型
      • 通过whatis命令可以进一步知道它们都在eden之中分配给main线程的thread-local allocation buffer (TLAB)中
      • 用inspect命令来查看对象的内容
      • 对象头的第一个字段是mark word,记录该对象的GC状态、同步状态、identity hash code之类的多种信息。
      • 对象头的第二个字段是个类型信息指针,klass pointer。这里因为默认开启了压缩指针,所以本来应该是64位的指针存在了32位字段里。
      • 最后还有4个字节是为了满足对齐需求而做的填充(padding)。
      • HotSpot VM内部使用直接指针来实现Java引用
        • 在64位环境中有可能启用“压缩指针”的功能把64位指针压缩到只用32位来存。压缩指针与非压缩指针直接有非常简单的1对1对应关系,前者可以看作后者的特例
        • 幸好HSDB内建了revptrs命令,可以找出“反向指针”——如果a变量引用着b对象,那么从b对象出发去找a变量就是找一个“反向指针”
        • revptrs 0x00000000fa49a710
          • Oop for java/lang/Class @ 0x00000000fa499b00
        • whatis / inspect
        • Serviceability Agent对GenCollectedHeap系的GC支持得比较好,而对另外俩GC(Parallel GC和G1 GC)支持得没那么好。
        • 猜您是在用Parallel GC?其实稍微改造一下Serviceability Agent的Java部分就可以让whatis正确显示在哪里了。
  • References

    • 通过HSDB来了解String值的真身在哪里
    • 借HSDB来探索HotSpot VM的运行时数据

你可能感兴趣的:(The Top-Level HotSpot Debugger - HSDB)