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. 子类构造方法
相关文章
|
13天前
|
缓存 easyexcel Java
Java EasyExcel 导出报内存溢出如何解决
大家好,我是V哥。使用EasyExcel进行大数据量导出时容易导致内存溢出,特别是在导出百万级别的数据时。以下是V哥整理的解决该问题的一些常见方法,包括分批写入、设置合适的JVM内存、减少数据对象的复杂性、关闭自动列宽设置、使用Stream导出以及选择合适的数据导出工具。此外,还介绍了使用Apache POI的SXSSFWorkbook实现百万级别数据量的导出案例,帮助大家更好地应对大数据导出的挑战。欢迎一起讨论!
108 1
|
6天前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
9天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
34 17
|
1天前
|
存储 缓存 安全
Java内存模型(JMM):深入理解并发编程的基石####
【10月更文挑战第29天】 本文作为一篇技术性文章,旨在深入探讨Java内存模型(JMM)的核心概念、工作原理及其在并发编程中的应用。我们将从JMM的基本定义出发,逐步剖析其如何通过happens-before原则、volatile关键字、synchronized关键字等机制,解决多线程环境下的数据可见性、原子性和有序性问题。不同于常规摘要的简述方式,本摘要将直接概述文章的核心内容,为读者提供一个清晰的学习路径。 ####
11 2
|
2天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
2天前
|
存储 安全 Java
什么是 Java 的内存模型?
Java内存模型(Java Memory Model, JMM)是Java虚拟机(JVM)规范的一部分,它定义了一套规则,用于指导Java程序中变量的访问和内存交互方式。
8 1
|
9天前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
8天前
|
存储 运维 Java
💻Java零基础:深入了解Java内存机制
【10月更文挑战第18天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
21 1
|
11天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
18天前
|
存储 Java 数据管理
Java零基础-Java对象详解
【10月更文挑战第7天】Java零基础教学篇,手把手实践教学!
23 6