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
网友评论