Java对象详解

一、Java对象的组成

在这里插入图片描述

1.对象头

运行时数据

存储对象运行时的数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据官方成为“Mark Word”,它的长度在32位和64位的虚拟机中分别是32bit和64bit。32bit的HotSpot虚拟机中,当对象未被锁定时的组成如下表:
在这里插入图片描述

类型指针

对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例

2.实例数据

对象真正存储的有效信息,也是在程序中所定义的各种类型的字段内容

3.对齐填充

这部分不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,也就是说对象必须是8字节的整数倍,因此当实例数据不是8字节的倍数的时候就需要占位符来填充。

二、对象创建的流程

  1. 虚拟机接收到new指令
  2. 检查这个指令的参数能否在常量池中定位到一个类的符号引用,并且这个类是否已经被加载、解析和初始化过,如果没有则先执行类的加载过程
  3. 虚拟机为新生对象分配内存空间
  4. 将对象中的实例数据都初始化为零值
  5. 设置对象的header部分的数据
  6. 设置对象的实例数据(执行构造器)
    内存分配

对象大小在类加载完成后就可以完全确定。内存分配有两种分配方式:指针碰撞和空闲列表

  • 指针碰撞:前提是堆内存中的空闲空间十分的规整,使用与未使用的空间全部为连续,只需移动一下指针就可以了
  • 空闲列表:针对堆内存中的空间零散的存在,虚拟机维护着一个列表,记录着哪里被分配了,哪里还空闲。

三、Java对象的访问方式

一般来说,一个Java的引用访问涉及到3个内存区域:JVM栈,堆,方法区。以最简单的本地变量引用:Object obj = new Object()为例:

  • Object obj表示一个本地引用,存储在JVM栈的本地变量表中,表示一个reference类型数据;
  • new Object()作为实例对象数据存储在堆中;
  • 堆中还记录了Object类的类型信息(接口、方法、field、对象类型等)的地址,这些地址所执行的数据存储在方法区中;

在Java虚拟机规范中,对于通过reference类型引用访问具体对象的方式并未做规定,目前主流的实现方式主要有两种:

1.通过句柄访问

在这里插入图片描述
通过句柄访问的实现方式中,JVM堆中会专门有一块区域用来作为句柄池,存储相关句柄所执行的实例数据地址(包括在堆中地址和在方法区中的地址)。这种实现方法由于用句柄表示地址,因此十分稳定。

2.通过直接指针访问

在这里插入图片描述
通过直接指针访问的方式中,reference中存储的就是对象在堆中的实际地址,在堆中存储的对象信息中包含了在方法区中的相应类型数据。这种方法最大的优势是速度快,在HotSpot虚拟机中用的就是这种方式。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值