借助HSDB查看Java类对应的klass模型

问题一:Java的每个类被加载到JVM中,他们对应的C++类是什么?

答:klass模型

问题二:在JDK8中,Java类存储在方法区还是堆区?

普通的Java类,在JVM中对应的C++类是InstanceKlass,存储在方法区(String)

Java类对应的Class对象,在JVM中对应的C++类是 InstanceMirrorKlass,存储在堆区(String.class)

基本类型包括 boolean、byte、char、short、int、long、float、double,
如果是基本类型数组,在JVM中对应的C++类是 TypeArrayKlass
如果是引用类型数组,在JVM中对应的C++类是 ObjArrayKlass

创建一个Java测试类并运行:

public class Hello {

  private int a = 10;
  private static int b = 20;

  public static void main(String[] args) {
    int[] intArr = new int[1];
    Hello[] refArr = new Hello[1];
    Class<Hello> clazz = Hello.class;

    while (true);
  }
}

接下来,启动HSDB并连接到Hotspot进程 点击了解更多

完成 Attach to Hotspot process如何通过HSDB查看一个Java类对应的C++类呢?

方式一类向导 Class Browser

对于非数组,我们可以用类向导来查看它的klass模型
数组在 Class Browser 中是找不到的,因为数组是运行时动态创建的,没有真正的实体,因此使用类向导找不到。

选择顶部菜单栏 Tools | Class Browser,并找到类 Hello 对应的内存地址 0x0000000100060828 并复制下来:

接着再次选择顶部菜单栏 Tools | Inspector,在 Address / C++ Expression 后面输入 Hello 对应的内存地址 0x0000000100060828,然后键盘按下回车。

方式二通过对象

通过线程找到对应的栈帧,查看对象 oop 模型,查看 klass pointer

完成 Attach to Hotspot process,默认会弹出一个 Java Threads,点击 main 达到选中效果(该行蓝色背景区别于未选中的行),接着点击下图红框中的 Stack Memory 按钮:

打开的 Stack Memory for main 对话框,显示的 main 线程的栈帧:

对象首地址 C++类 局部变量名 Inspector
0xa3cf4878 oop clazz
0xa3cf6d60 ObjArray refArr
0xa3cf6ce0 [I intArr
0xa3cf6cd0 ObjArray args

[I 这个是 java描述符
_metadata._compressed_klass 对应的就是类型指针 klass pointer

posted @ 2022-08-17 15:36  极客子羽  阅读(161)  评论(0编辑  收藏  举报