Java内存模型与访问定位

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

在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本身不需要修改

2.2、直接指针:

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

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

 

以上!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值