Class对象存储在Java堆中

        在JDK1.8完全废除永久代之前的JDK版本中,方法区是一个逻辑分区,实际是java堆的一部分,但是有Non-heap的标记,以便区分。

       众所周知, java中new处的对象存放在java堆中,而对象的引用存放在虚拟机栈中。

        Java中的Class也是一个类,所以Class对象也存放在堆当中存放在方法区当中的是类的元数据,即类加载器从class文件中提取出来的类型信息、方法信息、字段信息等。

        Java的对象(包括class对象)中保存着指向相应类的元数据的引用,元数据中又保存着指向class对象的引用。

OOP-KLASS内存模型Class实例在堆中还是方法区中? - 小菜变大鸟 - 博客园

        在JVM中,使用了OOP-KLASS模型来表示java对象

        JVM加载一个类的时候会创建一个instanceKlass,用来表示这个类的元数据,包括常量池、字段、方法等。存放在方法区

        在new一个对象时,jvm创建instanceOopDesc,来表示这个对象,存放在区,其引用,存放在栈区;平时说的Java Object Layout就是instanceOopDesc,它用来表示对象的实例信息;instanceOopDesc对应java中的对象实例。

        HotSpot并没有把instanceKlass直接暴露给Java,而会另外创建对应的instanceOopDesc来表示java.lang.Class对象,并将后者称为前者的“Java镜像”,instanceKlass持有指向instanceOopDesc的引用。(_java_mirror便是该instanceKlass对Class对象的引用);

instanceOopDesc包含三部分:
1. 对象头,也叫Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等;
2. 元数据指针,即指向方法区的instanceKlass实例
3. 实例数据;
4. 另外,如果是数组对象,还多了一个数组长度

总结:

  • instanceKlass保存类的元数据,存储在方法区,只有一份(同一个类加载器)。
  • instanceOopDesc保存类实例对象包括class对象),存储在堆中。一个类的实例对象可以有多个,但class对象只有一个(同一个类加载器),一个类的class对象与其类的元数据一一对应。
  • instanceOopDesc中包含指向相应的instanceKlass(类的元数据)的指针,而instanceKlass又保存着相应class对象(instanceOopDesc)的引用。
  • HotSpot通过InstanceOopDesc将类的元数据通过class对象间接暴露给java,class对象是java访问类的元数据的入口(因为class对象(InstanceOopDesc)中保存着指向元数据的指针)。
  • Person类的实例(Oop)-->Person类的元数据()-->Person类的class对象:解读(前提:同一个类加载器)
    • 每一个类的实例可以有多个,每个实例对象对应的Oop中对klass的引用都是同一个
    • 每一个类的元数据instanceKlass只有一个
    • 每一个类的class对象(Oop)也只有一个
    • 唯一的Klass与唯一的class对象一一对应,互相保存着对彼此的引用。
  •  不同类加载器产生的class对象不同,分布在堆中的不同地址中。
  • 这些引用关系支持着获取class对象三种方式的实现
    •  Class.forName("ClassName"):通过类的元数据中的class对象引用获得class对象
    •  object.getClass():通过实例对象中保存的对类的元数据的引用获取类的元数据(instanceKlass),通过instanceKlass中对class对象的引用获取class对象(instanceOopDesc)
    •  ClassName.class:通过类的元数据中的class对象引用获得class对象
  • Oop中对klass的引用支持【通过class对象创建类的实例对象】这一功能的实现

 

  • 20
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值