【Java笔记】JVM:对象在内存中是什么样的?如何计算对象占用的内存大小?

文章目录

Java对象的内存布局

Java中,一个实例对象在内存中的组成主要包括对象头、实例数据、补齐,而对象头则进一步包括markword与类型指针:

  • markword:包含了锁的信息、hashcode、gc信息等等
    • 大小8B
    • 锁信息:无锁、偏向锁、轻量级锁、重量级锁、自旋锁
    • gc信息:三色标记法标记的状态
    • hashcode
  • klass pointer 类型指针(有的也叫Class Metadata Address):指向对应数据类型的class,比如new Object就指向Object.class;
    • 大小8B,一般默认开启指针压缩就是4B。因为大部分机器32位指针寻址就够力;
  • instance data 实例数据:存放成员变量(基本数据类型就直接存储,类的实例存储其引用,比如String)
  • Padding:将对象整体大小对齐为8B大小
    • 因为这里说的是64位JVM,一次寻址范围64bit,即8B。

计算对象占用的内存大小

Openjdk jol

openjdk jol提供了计算对象内存布局的方法,即ClassLayout.parseInstance。

  1. 引入maven依赖

    xml 复制代码
    <!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
    <dependency>
        <groupId>org.openjdk.jol</groupId>
        <artifactId>jol-core</artifactId>
        <version>0.16</version>
    </dependency>
  2. 使用ClassLayout.parseInstance

    java 复制代码
    public static class MyClass{
    
    }
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        System.out.println(ClassLayout.parseInstance(myClass).toPrintable());
    }

来算几个

Object o = new Object() 该对象在内存中占用多少字节?

Object类本身不含成员变量,所以instance data为0,两个header word总共位8+4=12B,Padding补齐为16字节。

最终就是16B

基本数据类型作为成员变量的对象

  • 含有1个int的对象:16B。instance data为4B,两个Header word(markword+klass Pointer)12B,共16B,刚好是8的倍数,不用Padding;
  • 含有2个int的对象:24B。instance data为2*4=8B,两个Header word(markword+klass Pointer)12B,此时共20B,需要4B的Padding凑成8的倍数,因此共24B;
  • 含有两个int一个boolean的对象:24B。instance data为2*4+1=9B,两个Header word(markword+klass Pointer)12B,此时共21B,需要3B的Padding凑成8的倍数,因此共24B;

有实例对象作为成员变量的对象

java 复制代码
public static class MyClass{
    int a;
    int b;
    boolean flag;
    String s = "Hello";
}
public static void main(String[] args) {
    MyClass myClass = new MyClass();
    System.out.println(ClassLayout.parseInstance(myClass).toPrintable());
}

可以看出,由于String是另一个对象,Mycalss的instance data只存储其引用。

相关推荐
朝朝辞暮i几秒前
C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?
java·c++·算法
弹简特2 分钟前
【Java项目-企悦抽】16-抽奖模块01-获取活动完整信息接口实现
java·开发语言·状态模式·springboot
泡茶喝茶写代码1 小时前
A股量化数据工程:从 REST 接口到策略信号(第 1 篇):指数列表与实时行情接入
java·python·股票数据api·股票数据·股票数据api接口·股票api数据接口·股票量化数据接口
Sarvartha1 小时前
接口基础知识
java·开发语言
知产xiao_xin1 小时前
了解商号权
经验分享·笔记·知识产权
不才不才不不才1 小时前
Spring 源码系列(29): 20 道高频面试题源码级解析合集
java·后端·spring
索隆zoro1 小时前
Army 的可插拔架构:army-jdbc 与方言模块
java·后端
进击的横打2 小时前
【人工智能】卡片笔记法:从原子化思考到知识网络构建
笔记
小蒜学长2 小时前
校园社团招新网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·校园社团招新网站
Dovis(誓平步青云)2 小时前
多个链接不等于多份证据,新闻核验看板怎样合并来源
java·服务器·前端·javascript·人工智能·pdf·电脑