Java对象内存布局

简介: Java一切皆对象,那么一个对象里到底包含什么呢

Java对象存储内存布局


众所周知,Java是一门面向对象的语言,那么一个对象在内存中都包含什么东西呢,首先,对象大部分是存储在堆上的(逃逸除外)。


那么对象存储在堆中主要分为三个部分

  1. 对象头、对象实例数据、对齐补充(数组会多一个数组长度)
  2. 对象头:
  1. mark word:存储对象的hashCode、锁信息(锁升级)或分代年龄或GC标志等信息
  2. 类型指针:存储指向对象所属类(元数据中class文件)的指针,JVM通过这个确定这个对象属于哪个类
  1. 对象实例数据:
  1. new出的对象信息,存放类的属性数据信息,包括父类的属性信息;
  1. 对齐补充
  1. 数组对象会多对齐填充
  2. JVM要求对象占用的空间必须是8 的倍数,方便内存分配(以字节为最小单位分配),因此这部分就是用于填满不够的空间凑数用的。



Java对象的访问定位

  1. 主流的访问方式主要有句柄直接指针
  2. 句柄
  1. Java堆中划分出一块内存作为句柄池,栈中的reference中存储的事对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息
  1. 直接指针
  1. java堆中对象的内存布局必须考虑如何防止访问类型数据的相关信息,reference中存储的直接是对象地址。
  1. 直接指针访问对象不需要多一次间接访问开销,而句柄方便在对象地址发生改变时(垃圾回收会移动对象地址)只需要改变句柄中的指针引用本身不需要改变。

image.png


Java对象的创建过程

  1. 虚拟机遇到new指令时,先去检查指定的类是否被加载、验证、准备为类中的所有静态变量分配内存空间,并为其设置一个初始值解析、初始化过。
  2. 类检查后虚拟机为新对象分配内存
  1. 如何保证并发情况分配堆内存安全
  2. 虚拟机采用CAS配上失败重试保证原子性
  3. 把内存分配交给线程,在创建线程时分配空间,把分配内存的任务交给线程支配。通过TLAB(Thread local Allocation Buffer)开启
  1. 分配完内存后设置对象头,如哪个类的实例、hashcode、类的元数据信息指针(方法区)
  2. 执⾏ init ⽅法(内核方法),初始化成员变量,执⾏实例化代码块,调⽤类的构造⽅法,并把堆内对象的⾸地址赋 值给引⽤变量。  



Java对象分配内存是否线程安全

  1. CAS 加失败重试保证更新原⼦性。
  2. 把内存分配按线程划分在不同空间,即每个线程在 Java 堆中预先分配⼀⼩块内存,叫做本地线程分配缓冲 TLAB,哪个线程要分配内存就在对应的 TLAB 分配,TLAB ⽤完了再进⾏同步。  



Java类实例化顺序

  1. 父类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
  2. 子类静态成员和静态初始化块 ,按在代码中出现的顺序依次执行
  3. 父类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
  4. 父类构造方法
  5. 子类实例成员和实例初始化块 ,按在代码中出现的顺序依次执行
  6. 子类构造方法
相关文章
|
3天前
|
安全 Java 编译器
java中类与对象回顾总结-2
java中类与对象回顾总结
18 3
|
3天前
|
Java 编译器
java中类与对象回顾总结-1
java中类与对象回顾总结
14 3
|
3天前
|
存储 Java
深入理解Java虚拟机:JVM内存模型
【4月更文挑战第30天】本文将详细解析Java虚拟机(JVM)的内存模型,包括堆、栈、方法区等部分,并探讨它们在Java程序运行过程中的作用。通过对JVM内存模型的深入理解,可以帮助我们更好地编写高效的Java代码,避免内存溢出等问题。
|
1天前
|
移动开发 前端开发 JavaScript
Java和web前端,IT新人该如何选择?,2024年最新Web前端内存优化面试
Java和web前端,IT新人该如何选择?,2024年最新Web前端内存优化面试
|
2天前
|
存储 算法 Java
Java一分钟之-Java内存模型与垃圾回收机制概览
【5月更文挑战第16天】本文简述Java内存模型(JMM)和垃圾回收(GC)机制。JMM包括栈、堆、方法区、程序计数器和本地方法栈。GC负责回收不再使用的对象内存,常用算法有新生代、老年代和全堆GC。文章讨论了内存溢出、死锁和GC性能等问题,提出了解决方案,如调整JVM参数和优化GC策略。此外,还强调了避免内存泄漏、大对象管理及正确释放资源的重要性。理解这些概念有助于提升Java应用的性能和稳定性。
13 1
|
3天前
|
消息中间件 Java RocketMQ
MQ产品使用合集之在同一个 Java 进程内建立三个消费对象并设置三个消费者组订阅同一主题和标签的情况下,是否会发生其中一个消费者组无法接收到消息的现象
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
10 1
|
3天前
|
存储 安全 Java
Python中的引用和赋值机制允许变量引用内存中的对象,并通过引用计数来管理对象的生命周期
【5月更文挑战第14天】Python中的变量是对象引用,不存储数据,而是在内存中创建对象。赋值操作创建新变量并使其指向已有对象。引用计数用于管理对象生命周期,引用数为0时对象被回收。理解这些机制对编写高效Python代码很重要。
18 6
|
3天前
|
Java 编译器
【Java开发指南 | 第一篇】类、对象基础概念及Java特征
【Java开发指南 | 第一篇】类、对象基础概念及Java特征
11 4
|
3天前
|
安全 Java 数据安全/隐私保护
Java一分钟之-Java反射机制:动态操作类与对象
【5月更文挑战第12天】本文介绍了Java反射机制的基本用法,包括获取Class对象、创建对象、访问字段和调用方法。同时,讨论了常见的问题和易错点,如忽略访问权限检查、未捕获异常以及性能损耗,并提供了相应的避免策略。理解反射的工作原理和合理使用有助于提升代码灵活性,但需注意其带来的安全风险和性能影响。
23 4
|
3天前
|
Java
【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态
【JAVA基础篇教学】第五篇:Java面向对象编程:类、对象、继承、多态