首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java对象内存布局

Java对象内存布局

原创
作者头像
诺浅
修改于 2020-08-19 06:42:24
修改于 2020-08-19 06:42:24
1.3K0
举报
文章被收录于专栏:工具使用工具使用

Java对象的内存布局

一个Java对象在内存中包括三部分

  1. 对象头
  2. 实例数据
  3. 补齐填充
在这里插入图片描述
在这里插入图片描述

对象头

对象头又分为以下三部分

  • Mark Word:Mark Word存储了对象的hashCode、GC信息、锁信息三部分。在32位系统占4字节,在64位系统中占8字节;
  • Class Pointer:用来指向对象对应的Class对象(其对应的元数据对象)的内存地址。在32位系统占4字节,在64位系统中占8字节,如果64位开启了指针压缩则4字节。
  • Length:如果是数组对象,还有一个保存数组长度的空间,占4个字节;

对象头内存分布图

在这里插入图片描述
在这里插入图片描述

对象实际数据

对象实际数据包括了对象的所有成员变量,其大小由各个成员变量的大小决定,,比如:byte和boolean是1个字节,short和char是2个字节,int和float是4个字节,long和double是8个字节,reference是4个字节(64位系统中是8个字节)。

在这里插入图片描述
在这里插入图片描述

对齐填充

Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数。例如,一个包含两个属性的对象:int和byte,这个对象需要占用8+4+1=13个字节,这时就需要加上大小为3字节的padding进行8字节对齐,最终占用大小为16个字节。

如何打印Java对象内存布局

代码语言:txt
AI代码解释
复制
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>
代码语言:txt
AI代码解释
复制
public class TestMemory {
    public static void main(String[] args) {
        System.out.println(VM.current().details());
        System.out.println(ClassLayout.parseClass(A.class).toPrintable());
    }
}

class A{
    long i;
}
在这里插入图片描述
在这里插入图片描述

练习

以下均指默认开启指针压缩的情况

一、static变量不占用空间

代码语言:txt
AI代码解释
复制
public class A{
    int a;
    long b;
    static int c;
}

public class TestMemory {

    public static void main(String[] args) {
        A a = new A();
        System.out.println(ClassLayout.parseInstance(a).toPrintable());
    }
}
在这里插入图片描述
在这里插入图片描述

二、不满8的倍数填充字节

代码语言:txt
AI代码解释
复制
public class TestObjectSize {
    int a;
    int b;
}
在这里插入图片描述
在这里插入图片描述

三、引用占4个字节

代码语言:txt
AI代码解释
复制
public class A {
    Long[] a=new Long[]{1L,2L,3L};

    public Long[] getA() {
        return a;
    }

    public void setA(Long[] a) {
        this.a = a;
    }
}
在这里插入图片描述
在这里插入图片描述

四、数组对象长度占4个字节,有长度的数组按数组长度算占用字节

代码语言:txt
AI代码解释
复制
public class A {
    Long[] a=new Long[10];

    public Long[] getA() {
        return a;
    }

    public void setA(Long[] a) {
        this.a = a;
    }
}

public class TestMemory {

    public static void main(String[] args) {
        A a = new A();
        System.out.println(ClassLayout.parseInstance(a.getA()).toPrintable());
    }
}
在这里插入图片描述
在这里插入图片描述

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
承前启后,Java对象内存布局和对象头
大家好,我是小高先生。在我之前的一篇文章《并发编程防御装-锁(基础版)》中,我简要介绍了锁的基础知识,并解释了为什么Java中的任何对象都可以作为锁。在那里,我提到了对象头中有一个指向ObjectMonitor的指针,但没有深入探讨Java对象的内存结构。本文将引导大家深入了解Java对象的内存布局以及对象头结构,帮助大家更好地理解Java中的对象和锁,并为之后学习synchronized和锁升级打下基础。
小高先生
2024/02/21
2450
面试专题:Synchronized 锁的升级过程(锁/对象状态)及底层原理
这个面试题其实涉及到的底层知识比较多,在Java中都知道synchronized,这是一个关键字,为什么使用了之后,可以结果多线程安全问题。里面内部流程是怎样的呢?加锁是加在哪里?金三银四越来越卷,面试官不再是,单纯的问如何解决线程安全,有没有使用过synchronized,而是想知道synchronized底层的知识点。本文就深入讲解synchronized底层原理,对象加锁是如果一步一步实现的。
小明爱吃火锅
2024/02/18
1.5K0
面试专题:Synchronized 锁的升级过程(锁/对象状态)及底层原理
深入解析JVM-Java对象头组成
上一章节带着大家初探JVM的类加载机制,以及双亲委派机制,本文主要介绍了Java对象头的组成以及详解
janyxe
2022/04/17
2.9K0
深入解析JVM-Java对象头组成
对象的内存布局解析
Hotspot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据 (Instance Data)和对齐填充(Padding)。
忧愁的chafry
2022/10/30
6430
对象的内存布局解析
new Object()到底占几个字节,看完这篇就彻底明白了
Java虚拟机栈是线程私有的,没有数据安全问题,而堆相比较于Java虚拟机栈而言更为复杂。
公众号 IT老哥
2020/12/29
6300
new Object()到底占几个字节,看完这篇就彻底明白了
多线程基础(五):java对象的MarkWord及synchronized锁升级过程
在前面聊过了如何使用synchronized,以及synchronized不同的加锁方式分别锁的是哪些对象。本文对synchronized底层的原理进行深层次的分析。
冬天里的懒猫
2020/09/10
9870
多线程基础(五):java对象的MarkWord及synchronized锁升级过程
理解Java对象:要从内存布局及底层机制说起,话说....
在上篇文章中我们提到,对象在JVM中是由一个Oop进行描述的。回顾一下,Oop由对象头(_mark、_metadata)以及实例数据区组成,而对象头中存在一个_metadata,其内部存在一个指针,指向类的元数据信息,就是下面这张图:
用户2242639
2023/09/02
2230
理解Java对象:要从内存布局及底层机制说起,话说....
JDK之JVM中Java对象的头部占多少byte
    从Stackoverflow上看到,Java对象头部有一个mark word和一个klass pointer,
克虏伯
2019/04/15
1.4K0
JDK之JVM中Java对象的头部占多少byte
boolean 与boolean数组内存布局-Java快速进阶教程
首先,我们将检查 JVM 以查看对象大小。然后,我们将了解这些尺寸背后的基本原理。
jack.yang
2025/04/05
1080
JUC并发编程之Synchronized关键字详解
在多线程中,有可能会出现多个线程同时访问同一个共享、可变资源的情况,这个资源我们称之其为临界资源;这种资源可能是:对象、变量、文件等。
黎明大大
2021/07/23
3980
JUC并发编程之Synchronized关键字详解
JVM - 剖析Java对象头Object Header之对象大小
JVM - 写了这么多年代码,你知不道new对象背后的逻辑? 中大体介绍了Java中 new 对象背后的主要流程,其中对象头的部分,我们仅仅是点到为止,这里我们深入剖一下Object Header的奥秘 。
小小工匠
2021/08/17
1.7K0
初步了解Java对象布局
其中byte、short、int、long都是表示整数的,只不过他们的取值范围不一样
iiopsd
2023/10/17
2230
初步了解Java对象布局
终于我用JOL打破了你对java对象的所有想象
使用面向对象的编程语言的好处就是,虽然没有女朋友,但是仍然可以new对象出来。Java是面向对象的编程语言,我们天天都在使用java来new对象,但估计很少有人知道new出来的对象到底长的什么样子,是美是丑到底符不符合我们的要去?
程序那些事
2020/07/07
1K0
[JAVA基础] - JVM对象内存布局及锁的标记位
一、对象布局 1、对象头 1)存储对象自身的运行时数据 hash码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。占位32/64位虚拟机分别占32/64个比特,官方称"Mark Word" 2)类型指针 指向对象的元数据,如果是数组,还会存储数组长度。 2、实例数据 3、对齐填充 要求对象是8的整数倍,对象头已经是8位的整数倍,只填充实例数据即可。 二、Object o = new Object()内存占用情况 占用16个字节 对象头12个字节,对齐填充4个字
夹胡碰
2022/05/19
4850
[JAVA基础] - JVM对象内存布局及锁的标记位
synchronized锁升级原理
KlassWord(下图_klass)占32位 64位系统的Klass Word不是32位,默认64位,开启指针压缩后为32(感谢评论老哥的指出)
CBeann
2023/12/25
2060
synchronized锁升级原理
JVM系列之:详解java object对象在heap中的结构
在之前的文章中,我们介绍了使用JOL这一神器来解析java类或者java实例在内存中占用的空间地址。
程序那些事
2020/07/24
1.2K0
JVM系列之:详解java object对象在heap中的结构
面试被问:一个Java对象占多少内存?
来源:https://my.oschina.net/luozhou/blog/3175463
田维常
2020/03/11
2.7K0
JVM - 剖析Java对象头Object Header之指针压缩
同一个对象, 不开启指针压缩 8字节 存入堆中和 开启指针压缩4字节存入堆中,哪个更好一些,显而易见。
小小工匠
2021/08/17
1.1K0
CAS、ABA问题、锁升级
1.首先读取该值: 假如该值N初始状态为0,那么读取该值以后保存到自定义的变量E中
孑小白
2021/05/13
4740
CAS、ABA问题、锁升级
JVM 从入门到放弃之 Java 对象创建过程
当虚拟机遇到一个字节码 new指令的时候,首先去检查这个指令的参数是否能够在常量池中定位到一个类的符号引用。并且检查这个符号引用代表的类是否被虚拟机类加载器加载。如果没有,必须先执行类加载的流程。
没有故事的陈师傅
2022/04/05
7160
JVM 从入门到放弃之 Java 对象创建过程
相关推荐
承前启后,Java对象内存布局和对象头
更多 >
LV.2
百联全渠道电子商务有限公司高级软件工程师
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档