深入理解JVM--JVM中的对象

概述

当今在实际上有三种JVM:

  1. SUN 公司最早改良的HotSpot;
  2. BEA 公司的: JRockit; (最初三个SUN公司的老员工创立)
  3. IBM的JVM’S;

建立对象就是为了使用对象,我们的Java程序通过栈上的reference数据来操作堆上的具体对象。对象的访问方式由虚拟机实现而定,目前主流的访问方式有①使用句柄和②直接指针两种:

这两种对象访问方式各有优势。使用句柄来访问的最大好处是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改。使用直接指针访问方式最大的好处就是速度快,它节省了一次指针定位的时间开销。

对象的创建

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。分配方式有 “指针碰撞” 和 “空闲列表” 两种,选择那种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。

接下来,虚拟机要对对象进行必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希吗、对象的GC分代年龄等信息。这些信息存放在对象头中,根据虚拟机当前运行状态的不同,如是否启用偏向锁等,对象头会与不同的设置方式。
new指令执行完后,再按照程序员的意愿执行init方法后一个真正可用的对象才诞生。

对象的内存布局

在Hotspot虚拟机中,对象在内存中的布局可以分为3快区域:对象头、实例数据和对齐填充。

  1. 对象头
    对象头包含两部分,第一部分用于存储对象自身运行时的数据,包括GC分代年龄、哈希码、锁状态、线程持有的锁等数据,这部分的数据长度在32位和64位虚拟机中分别为32位和64位,被称为“Mark Word”。
    对象头的另一部分用于存储对象的类元数据的指针,虚拟机通过这个指针可以知道对象是哪个类的实例。

  2. 实例数据
    实例数据用于存储在程序代码中定义的各种类型的字段内容,也包含从父类继承来的。这部分数据的存储顺序会受到虚拟机分配策略参数和字段在代码中定义的顺序的影响。

  3. 对齐填充
    对齐填充部分不是必然存在的,也没有什么特别的含义,仅仅起占位作用。 因为Hotspot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的倍数(1倍或2倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

对象的访问定位

Java的引用类型是最为重要的数据处理模型,而整个的数据引用类型数据处理之中会牵扯到:堆内存、栈内存、方法区。
以一个最简但的程序代码为主:
“Object obj = new Object()”,实例化了一个Object类对象。
“Object obj”:描述的是保存在栈内存之中,而保存有堆内存的引用,这个数据会保存在本地变量表中;
“new Obect()”:一个真正的对象。保存在堆内存之中;

直观的思路整个引用的操作:

  • 新定义的对象的名称保存在本地变量表,
  • 而后在这块区域里面需要确定好与之对应的栈内存;
  • 通过变量表中的栈地址可以找到堆内存。
  • 利用堆内存的对象进行本地方法的调用(方法区);
  1. 使用句柄
    如果使用句柄的话,那么Java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息。这种模式的准确度很高,但过程较为繁琐
    在这里插入图片描述
  2. 直接指针
    而java中是没有句柄的,java中直接利用的对象保存模式,也就是说堆内存中,不需要保存句柄,而reference中存储的直接就是对象的地址。就相当于省略了句柄到对象之间的查找。而后这个对象可以直接进行Java方法区的调用
    在这里插入图片描述

这里是引用
https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247483910&idx=1&sn=246f39051a85fc312577499691fba89f&chksm=fd985467caefdd71f9a7c275952be34484b14f9e092723c19bd4ef557c324169ed084f868bdb#rd
https://blog.csdn.net/qq_34707744/article/details/79279979

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值