JVM类加载
Klass
class和klass的区别:
- class是java类(java代码
- klass是java类在JVM的存在形式(c++代码
Klass类分别由InstanceKlass和ArrayKlass继承,其中InstanceClass用来表示普通的java类即非数组类,ArrayKlass是来表示Java数组的元信息。
InstanceKlass
-
普通类对应的是instanceKlass类的实例。
类加载器将.class文件加载进系统,然后将.class文件生成的类的元信息就是存储在InstanceKlass的。 -
InstanceKlass的几个子类又去存放子类对应存放的东西,由此也可以看到class对象和存放元信息的结构是分开的(元信息是在InstanceKlass,class对象是在InstanceMirrorKlass
-
对象内存结构的klass pointer中的klass就是指InstanceKlass及其子类
-
我们把java程序中的一个地址在 HSDB解析出来就可以看到
java中的类在jvm中是InstanceKlass
class对象是InstanceMirrorKlass
InstanceMirrorKlass(镜像类)
InstanceMirrorKlass:用于表示java .lang.Class,java 代码中获取到Class对象,实际上就是这个C++ 类的实例。
InstanceMirrorKlass存的是Class对象,存放在堆区。
InstanceRefKlass
InstanceRefKlass:用于表示java/lang/ref/Reference类的子类
InstanceRefKlass存的是引用
为什么引用要单独用一个类表示呢,因为JVM的垃圾回收机制会对引用的做特殊处理。
InstanceClassLoaderKlass
InstanceClassLoaderKlass:用于遍历某个加载器加载的类
ArrayKlass
-
Java中的数组不是静态数据类型,是动态数据类型,即是运行期生成的。
我们可以查看字节码看出来 java中的数组是运行时动态生成的:-
普通类型
newarray:创建一个指定的原始类型(int,float.char…)的数组,并将其引用值压入栈顶 -
引用类型
anewarray:创建一个引用型(如类,接口,数组)的数组,并将其引用值压入栈顶
-
-
因此,ArrayKlass用来存储数组类的元信息
TypeArrayKlass
TypeArrayKlass:用于表示基本类型的数组
可以看到我们在java中new的基本类型的数组在jvm中是TypeArrayKlass
ObjArrayKlass
ObjArrayKlass:用于表示引用类型的数组
可以看到我们在java中new的引用类型的数组在jvm中是ObjArrayKlass
类的加载过程
类加载过程的7个阶段:
加载
加载过程主要做的三步:
- 通过类的全限定名获取存储该类的class文件
这里获取的class文件是二进制字节流(这里没有要求在那里获取,所以可以通过拓展,网络,zip 等等都可以获取到) - 解析成运行时数据,即InstanceKlass实例,存在方法区
将这个字节流锁代表的静态存储结构转化为方法区的运行时数据结构 - 在堆区生成该类的Class对象,即InstanceMirrorKlass实例
来源:oschina
链接:https://my.oschina.net/u/4416758/blog/4906861