Java内存模型与访问定位

一、Java对象在内存中的结构

Java内存模型与访问定位_第1张图片

在JVM中,使用OOP-KLASS模型来表示Java对象,关于OOP-KLASS模型如上图所示。
1.1、JVM在加载class时,会创建instanceKlass,表示该class的元数据(包括常量池、字段、方法等),存放在方法区;instanceKlass是JVM中的数据结构;
1.2、在new一个对象时,JVM创建instanceOopDesc来表示这个对象,存放在堆区,对象的引用存放在栈区;instanceOopDesc用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象;instanceOopDesc对应Java中的对象实例;
1.3、HotSpot JVM并不把instanceKlass暴露给Java,而会另外创建对应的instanceOopDesc来表示java.lang.Class对象,并将后者称为前者的“Java镜像”,klass持有指向oop引用(_java_mirror便是该instanceKlass对Class对象的引用);
1.4、要注意,new操作返回的instanceOopDesc类型指针指向instanceKlass,而instanceKlass指向了对应的类型的Class实例的instanceOopDesc;有点绕,简单说,就是User实例——>User类的元数据instanceKlass——>User类的Class。

instanceOopDesc就是指对象的实例,它包含三部分:
1.5、对象头,也叫Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等;
1.6、元数据指针,即指向方法区的instanceKlass实例 ,虚拟机通过这个指针来群定这个对象是哪个类的实例
1.7、实例数据
1.8、如果是数组对象,会多一个数组长度的数据区

 

二、对象的访问定位

Java程序需要通过栈上的reference引用来操作堆上的具体对象。reference只是一个指向对象的引用,具体的对象访问根据不同虚拟机有不同的实现,主流的访问方式有两种:使用句柄直接指针。HotSpot使用的是指针对象访问。

2.1、使用句柄:

如果通过句柄来访问对象,Java堆中会划出一块内存作为句柄池,reference中存储句柄地址,而句柄中包含对象的实例数据与类型数据各自的地址。这样就能访问到对象了

优势:reference中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要修改

Java内存模型与访问定位_第2张图片

2.2、直接指针:

直接指针,就是指reference中直接存储对象的地址。但是Java堆对象的布局中就必须考虑如何防止访问类型数据相关信息

优势:直接指针访问:速度快,它节省了一次指针定位的时间开销,由于对象的访问在JAVA中非常频繁,因此这类开销积少成多后也是非常可观的执行成本

Java内存模型与访问定位_第3张图片

 

以上!

你可能感兴趣的:(Java,Java虚拟机)