Hotspot Klass模型——Java类内存表示机制

目录

1、类继承结构

2、MetaspaceObj

3、Metadata

4、Klass

5、InstanceKlass

6、Method

7、Java vtable

8、Java itable 

9、InstanceKlass特殊子类

10、ArrayKlass


     在分析thread.cpp的create_vm函数中(参考《Hotspot启动和初始化源码解析》)发现JVM通过initialize_class函数来加载Java类,该函数是threap.cpp的一个静态函数,其函数定义如下:

  接着为main_thread创建thread_object即Java中的java.lang.Thread对象时使用了create_initial_thread函数,该函数返回了oop,实际是类oopDesc* 的别名,如下图:

 在《Java程序员自我修养——内存模型》中探讨过,Java对象在内存中是实例数据和类型数据相分离的,实例数据保存了一个指向类型数据的指针,即OOP(ordinary object pointer),因此猜测这里的Klass就是所谓的类型数据,oopDesc就是具体的实例数据了。

1、类继承结构

     在上述代码Klass处按crtl并点击即可进入到定义Klass的头文件kclass.hpp中,该文件的位于hotspot\src\share\vm\oops目录下,选中Klass,点击右键,选择Open Type Hierarchy即可显示该类的继承关系图了,如下:

选择其中某一个类如MetaspaceObj,右键选择Open即可进入定义该父类的头文件alloction.hpp,位于hotspot\src\share\vm\memory下,如下图:

2、MetaspaceObj

     该类是作为存放在Metaspace元空间的中类的基类,不能执行delete,否则会出现致命错误,注意该类没有定义虚函数。该类重载了new操作符,主要用于给共享只读的或者共享读写的类分配内存,该类定义了如下方法:

 该类定义了一个枚举Type用于表示对象类型,包含以下几种类型:

3、Metadata

      Metadata是内部表示类相关元数据的一个基类,注意Metadata定义了多个虚函数,其定义的方法如下:

其中identity_hash()方法返回的实际是该对象的内存地址,如下图:

 其中跟stack相关的三个方法是类重定义(class redefinition)期间使用的,跟Java栈帧无关。

4、Klass

     一个Klass提供两方面的功能:实现Java语言层面的类和提供多态方法的支持。C++类实例通过保存typeinfo指针实现RTTI,通过vtbl指针实现多态,Hotspot的Oop-Klass模型将这两者整合到Klass中,Java类实例只需保留一个Klass指针即可实现RTTI和多态,能够有效降低指针的内存占用。大致方案是用Oop表示Java实例,主要用于表示实例数据,不提供任何虚函数功能,Oop保存了对应Kclass的指针,所有方法调用通过Klass完成并通过Klass获取类型信息,Klass基于C++的虚函数提供对Java多态的支持。Klass作为父类主要职责是描述了类的继承关系, 其包含的重要属性如下:

     _layout_helper:_layout_helper是对象内存布局的一个组合描述符,如果不是InstanceKclass或者ArrayKlass,则该值为0.对InstanceKclass而言,该值表示对象的以字节为单位的内存占用空间,对ArrayKlass而言,该值是一个组合起来的假数字,包含4部分,具体怎么组合和解析由子类实现:

  1. tag:如果数组元素是对象实例则是0x80,否则是0xC0
  2. hsz: 数组头元素的字节数
  3. ebt:数组元素的类型,枚举值BasicType
  4. esz:数组元素大小,以字节为单位

该值因为被频繁查询,所以放在虚函数表指针的后面。

     _super_check_offset:用于快速查找supertype的一个偏移量

    _secondary_super_cache:Klass指针,上一次observed secondary supertype

    _secondary_supers:Klass指针数组,指向secondary supertype,即类实现的接口对应的Kclass

    _primary_supers:Klass指针数组,大小固定为8,指向primary supertypes,即默认继承的类如Object

    _name: 类名,如java/lang/String,[Ljava/lang/String

    _java_mirror:  oopDesc指针,此类对应的java/lang/Class实例,可以据此访问类静态属性

    _super:Klass指针,父类

    _subklass:Klass指针,子类

    _next_sibling:Klass指针,该类的下一个子类

    _next_link:Klass指针,ClassLoader加载的下一个Klass

    _class_loader_data :ClassLoaderData指针,加载该类的ClassLoader

    _modifier_flags: 修改标识,Class.getModifiers使用

    _access_flags:获取类的修饰符,如private类访问控制,final,static,abstract ,native等

测试用例如下:

package jvmTest;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;

interface interTest{
    void show();
}

class Base{
    private int a=1;
    public void print(){
        System.out.println("Base");
    }
}

class Base2 extends Base{
    public int a;

    public Base2(int a) {
        this.a = a;
    }
    public void print(){
        System.out.println("Base2");
    }
}

class A extends Base2 implements interTest  {
    public int b;
    public A(int a,int b) {
        super(a);
        this.b=b;
    }

    @Override
    public void show() {
        System.out.println("a->"+a+",b="+b);
    }
    public void print(){
        System.out.println("A");
    }
}

class B extends A{
    private int c;
    public B(int a, int b) {
        super(a, b);
        c=3;
    }
    @Override
    public void show() {
        System.out.println("a->"+a+",b="+b+",c="+c);
    }
    public void print(){
        System.out.println("B");
    }
}

public class MainTest {

    public static void main(String[] args) {
        A a=new A(1,2);
        a.show();
        A[] a2={a,new B(2,3)};
        while (true){
            try {
                System.out.println(getProcessID());
                Thread.sleep(600*1000);
            } catch (Exception e) {

            }
        }
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值