本文知识点
-
OOP和klass的概念
-
OOP和Klass源码
-
HSDB的使用
OOP和klass的概念
OOPS: 即普通对象指针,用来描述对象实例信息
Klass: Java类的C++对等体,用来描述Java类
总体上是多个OOP和一个Klass是对应的. 相当于一个类可以有多个实例
A a = new A() ; A a1 = new A();
a,a1 分别对应着不同的OOP, 对应着同一个Klass
OOP和Klass源码
OOP中有很多模块,
其中最常用的是
instanceOop , 表示一个java类型实例
oopsHierarchy: 描述了对象的表示层次,描述了klass的表示层次,并为OOPS指针oopDesc* 定义了别名
markOop: 表示对象头
Klass 中对应的是:
instanceKlass : 在虚拟机层面描述一个java类
OOP源码
首先看oopsHierarchy.hpp
文件中,可以看到在OpenJDK的源码中都是用oopDesc* 等Desc* 来表示的.
在虚拟机内部,通过instanceOop
来表示一个java对象,对象在内存中的布局可以分为连续的两部分, instanceOopDesc
和实例数据
其中 instanceOopDesc中有:
friend class VMStructs;
friend class JVMCIVMStructs;
private:
// 看MarkOop的内容
volatile markOop _mark;
union _metadata {
// 看下面instanceKlass的内容
Klass* _klass;
narrowKlass _compressed_klass;
} _metadata;
MarkOop 对象头里面的东西
在markOopDesc中, 我们可以看到对32位和64位的对象头是分开定义的,
32位/64位的markOop中的格式如下图所示,对不同的对象,有不同的布局.
hash: 保存对象的哈希码
age: 保存对象的分代年龄
biased_lock: 偏向锁标识位
lock: 锁状态标识位
JavaThread*: 保存持有偏向锁的线程ID
epoch: 保存偏向时间戳
instanceKlass
klass: 元数据指针, 包含了实例对象所属类型的元数据, 虚拟机在运行时,会频繁到本地内存中去找类的描述信息(jdk1.8之后)
instanceKlass 继承于Klass,两者一起描述了类所共有的信息,如类名称
Klass中的主要字段
如上图所示,有类名称, 父类, 子类,类加载器等信息,即使没有C++语言基础,看到这些名字也能猜出来大致意思
instanceKlass 在原有klass的基础之上多了注解,常量信息,下面截图只是一部分,但是我把文件名还有行号都截出来了, 本文只做抛砖引玉之用,还需要大家下载源码,跟着一步步自己去学习!
HSDB
本文使用的都是jdk11, jdk8的启动方法网上一大堆,可自行百度.
HSDB是调试虚拟机极其有用的一款内置工具,自JDK9及以后,启动方式稍有些变化,首先确定自己的jdk版本,我现在的是11.0.2,如下:
启动方式是:jhsdb hsdb
输入jvm 进程号点OK 就可以看到jvm内部一些信息