栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JVM学习之 如何计算一个类的对象占用的内存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JVM学习之 如何计算一个类的对象占用的内存

文章目录
  • 对象的内存布局
      • 对象头
          • Mark World
          • 类型指针
      • 实例数据
      • 对齐填充
  • 实战
        • 空的String对象:
        • 非空的String对象

本文的讨论都是基于 HotSpot 虚拟机

对象的内存布局

要知道一个类对象占用的内存,我们就必须要知道对象的内存布局。
对象在堆内存中的存储布局可以划分为三个部分: 对象头,实例数据,对齐填充

对象头

对象的对象头包括两类信息。第一类是存储对象自身的运行时数据,第二类是类型指针

Mark World

存储对象自身的运行时数据,如 哈希码,GC分代年龄、锁状态标志、线程持有的锁等等。这部分的数据长度在32位虚拟机中为4个字节,在64位虚拟机中是8个字节,官方称之为 Mark Word

类型指针

指向它的类型元数据的指针(指向它的Class对象的指针),大小是4个字节。Java虚拟机通过这个指针来确定该对象是哪个类的实例

实例数据

实例数据部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容。计算方式是累加,如下对象:

public class O {
    private int o1;
    private long o2
}

实例数据部分长度就是 int(4字节)+long(8字节)=12字节

对齐填充

第三部分就是对齐填充。HotSpot虚拟机的自动内存管理要求对象起始地址必须是8字节的整数倍,换句话说就是任何对象的大小都必须是8字节的整数倍。如果对象大小没到8字节的整数倍,那就需要通过对齐填充来补全。

实战

已经知道了对象的内存布局,我们就可以来尝试计算一个类对象占用的内存:
我们就来计算 String类的内存:

空的String对象:

我们先来查看String类里面的实例数据有哪些;

@Stable
private final byte[] value;
private final byte coder;
private int hash; // Default to 0
private boolean hashIsZero; // Default to false;
 private static final long serialVersionUID = -6849794470754667710L;
static final boolean COMPACT_STRINGS;

可以得到实例数据部分的字节是 数组对象 + byte(1字节)+ int(4字节)+ boolean(1字节) + long(8字节) + Boolean(1字节)

那么数组对象也是一个对象,它的占用内存是 对象头(8字节)+ 引用(4字节)+ 记录长度的int(4字节)=16字节。

所以空的String对象占用内存是 8+16+1+4+1+8+1+ 1字节(字节填充)=40字节

非空的String对象

非空的string对象比空的string对象只有在数组对象里的 实例数据部分变化了,其他都没变,
所以非空的String对象占用内存是 8+16+1+4+1+8+1+ 1字节(字节填充)=40+ n字节(n是byte数组的长度)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328056.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号