HSDB(Hotspot Debugger)
运行
1 | 图形界面 java -cp $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB |
本文使用的时命令行CLHSDB。
由于HSDB会先attach进程,然后暂停进程,所以线上慎用。。。
验证过程
使用到的类
1 | public class Main { |
VM参数
1 | -XX:+UseSerialGC // 默认的XX:+UseParallelGC, 我在scanoops 会报no such type的异常,不知道是不是bug... |
找到进程pid ,attach
1 | > jps |
查看堆中内存使用情况
1 | hsdb> universe |
可以看到堆中目前只使用了eden区域存放数据。
在该区域扫描我们建的类
1 | hsdb> scanoops 0x0000000012400000 0x0000000012961068 com.example.demo.Main |
扫到我们要的类,使用whatis
发现分配在TLAB中(我的环境时jdk8,默认TLAB优化时开启的)
使用inspect
进一步查看对象的信息
1
2
3
4hsdb> inspect 0x000000001275f610
instance of Oop for com/example/demo/Main @ 0x000000001275f610 @ 0x000000001275f610 (size = 16)
_mark: 1
_metadata._klass: InstanceKlass for com/example/demo/Main
Main只有静态变量,所以对象实例大小为16byte,在64位关闭指针压缩的情况下 MARK WORLD(8byte) 加上类型指针(8byte,开启压缩是4byte) 正好是16byte。
InstanceKlass就是指的是Class对象,所以这里就可以证明Class对象是存在堆中,而不是方法区
使用mem
找到具体地址 查看具体信息,mem addresss length
1 | hsdb> mem 0x000000001275f610 2 |
可以看到Class信息中
1
oop Klass::_java_mirror: Oop for java/lang/Class @ 0x000000001275d298 Oop for java/lang/Class @ 0x000000001275d298
_java_mirror表示该Klass的Java层镜像类(在Java7中由镜像类持有类型的静态成员)
1 | hsdb> whatis 0x000000001275d298 |
可以看到 该镜像中持有我们类中,创建的两个静态变量。
参考资料
https://book.douban.com/subject/25847620/annotation
https://www.iteye.com/blog/rednaxelafx-730461#comments
https://www.tuicool.com/articles/ryQv2iB