HotSpot虚拟机实现中几个重要的类

来源:互联网 发布:查看mysql 用户和授权 编辑:程序博客网 时间:2024/05/29 08:05

基于:openjdk-8-src-b132-03_mar_2014

HotSpot JVM没有将Java对象直接通过虚拟机映射到C++对象,而是设计了一个Oop/Klass 模型,其中oop为Ordinary Object Pointer,用来表示对象的实例信息;klass用来保存描述元数据信息。

为什么要设计oop/klass这种二分模型的实现?
一个原因是不想让每个对象都包含vtbl(虚方法表),其中oop中不含有任何虚函数,虚表只保存于klass中,可以进行method dispatch。

typedef juint narrowKlass;
typedef juint narrowOop;
typedef class markOopDesc* markOop;
typedef class oopDesc* oop;
typedef class instanceOopDesc* instanceOop;

markOop为指向markOopDesc(对象头)的指针

oop为指向oopDesc的指针

class instanceOopDesc : public oopDesc {}

instanceOop为指向instanceOopDesc(java中Class的实例)的指针

class oopDesc {  friend class VMStructs; private:  volatile markOop  _mark;  union _metadata {    Klass*      _klass;    narrowKlass _compressed_klass;  } _metadata;

oopDesc对象包含两部分数据:_mark 和 _metadata;
1、_mark是markOop类型对象,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等。
2、_metadata是一个联合体,_klass和_compressed_klass都指向InstanceKlass对象的指针,其中_compressed_klass指向的是经过压缩的对象;在联合体中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度。
3、_klass字段建立了oop对象与klass对象之间的联系;
1与2都成了Java对象的对象头。

VMStructs:This class is a friend of most classes, to be able to access private fields.

// An InstanceKlass is the VM level representation of a Java class.// It contains all information needed for at class at execution runtime.//  InstanceKlass layout://    [C++ vtbl pointer           ] Klass//    [subtype cache              ] Klass//    [instance size              ] Klass//    [java mirror                ] Klass//    [super                      ] Klass//    [access_flags               ] Klass//    [name                       ] Klass//    [first subklass             ] Klass//    [next sibling               ] Klass//    [array klasses              ]//    [methods                    ]//    [local interfaces           ]//    [transitive interfaces      ]//    [fields                     ]//    [constants                  ]//    [class loader               ]//    [source file name           ]//    [inner classes              ]//    [static field size          ]//    [nonstatic field size       ]//    [static oop fields size     ]//    [nonstatic oop maps size    ]//    [has finalize method        ]//    [deoptimization mark bit    ]//    [initialization state       ]//    [initializing thread        ]//    [Java vtable length         ]//    [oop map cache (stack maps) ]//    [EMBEDDED Java vtable             ] size in words = vtable_len//    [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size//      The embedded nonstatic oop-map blocks are short pairs (offset, length)//      indicating where oops are located in instances of this klass.//    [EMBEDDED implementor of the interface] only exist for interface//    [EMBEDDED host klass        ] only exist for an anonymous class (JSR 292 enabled)

HotSpot VM里,Klass用于描述能被GC的对象的类型信息的元数据对象。而Oop则用来描述能被GC的Java对象。

当在Java中new一个对象时,本质是在堆内存创建一个instanceOopDesc对象。

这里写图片描述

JVM可以通过对象引用准确定位到Java堆区中的instanceOopDesc对象,这样既可成功访问到对象的实例信息,当需要访问目标对象的具体类型时,JVM则会通过存储在instanceOopDesc中的元数据指针定位到存储在方法区中的instanceKlass对象上。

JVM 中,InstanceKlass、java.lang.Class的关系?
An InstanceKlass is the VM level representation of a Java class. It contains all information needed for at class at execution runtime. ClassFileParser将class文件在runtime解析成一个个InstanceKlass对象,这个对象是静态字节码文件在运行时Metaspace空间的一个映射。我们知道Java是一种支持反射的语言,为了能在Java层实现对定义类型的解构,JVM实现了InstanceKlass的一个java mirror的概念——java.lang.Class对象。
InstanceKlass类继承自Klass类,在Klass类中有一个成员变量,并且提供了相应的Setter/Getter函数实现:

// java/lang/Class instance mirroring this classoop       _java_mirror;oop java_mirror() const              { return _java_mirror; }void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); }             

在java_lang_Class类中,也提供了Class对象与Klass对象的转化函数:

static Klass* as_Klass(oop java_class);static void set_klass(oop java_class, Klass* klass);

Class类所提供的反射机制,最终都是通过JNI接口,调用相应的native方法,然后通过as_Klass函数转换成InstanceKlass对象,拿到定义类型的元数据信息的。

参考:
http://gao-xianglong.iteye.com/blog/2152345

https://www.jianshu.com/p/252e27863822

原创粉丝点击