Java 对象内存模型系列-1st

此心光明,亦复何言

『Everything is an object in java』在Java中,万物皆是对象。在我们日常工作中,我们都知道所谓的『对象』就是 Object 以及继承自Object的类的实例。另外我们也知道Java的对象都是存储分配在堆上的。(PS:这里不讨论JVM的优化内容)

开发这么过年,你优化性能的时候肯定考虑过一个对象的大小,但是你有没有想过上到底存储的是什么?这里的两个问题:

  1. 对象所占内存的大小;
  2. 对象在内存中的样子;

如果不知道What,就开始来猜大小,这就纯属XJB猜…

团长说了:『硬仗没你这打法,你小子不能只玩楞的』

带着这些疑问,这就正式进入本篇文章的话题,

1. 对象内存布局(Java Object Memory Structure)

我们先要弄明白对象在内存长什么样子,要想搞明白这个问题,

1.1 两种对象

在内存中,对象分为两种:

  1. 普通对象;
  2. 数组对象;
1.2 对象的构造

在JVM中,Java对象在内存中存储的布局可以分为下面几块区域:

  1. 对象头(Object Header)
  2. 实例数据(Instance Data)
  3. 对齐填充(Padding)
  4. 数组长度 (PS: 数组对象独有)
1.2.1 对象头

对象头又分为两部分:

  1. 标记字段(Mark Word):主要包含对象的身份(hashCode)以及一些标志位(锁,分代年龄等)
  2. Class对象指针(Class Pointer): 指向对象所对应的Class对象的内存地址
1.2.2 实例数据

即类中我们所定义的『成员变量』。友情提示:static修饰的变量不属于对象的内容。

1.2.3 对齐填充

Objects are 8 bytes aligned.(因为Java中所有的对象都要求8字节对齐,不够8字节的需要填充)

1.2.4 数组长度

该区域是数组对象独有的,见名知意,就是用来表示该数组对象的长度(元素个数)。

1.3 一图胜千言

下面这个图应该能满足你的需求吧。

Java内存模型

2. 验证结论

这里为了能看清普通对象数组对象的区别,定义没有任何成员变量的类.

2.1 普通对象
 public static class Empty{}

 public static void main(String[] args) {
         Empty instance = new Empty();
         System.out.println(ClassLayout.parseInstance(instance).toPrintable());
    }

结果如下:
在这里插入图片描述

2.2 数组对象
 public static void main(String[] args) {
         Empty[] arr = new Empty[10];
         System.out.println(ClassLayout.parseInstance(arr).toPrintable());
    }

  public static class Empty{}

结果如下:
在这里插入图片描述

3 总结

通过上面的结论,我们可以清楚的看出对象在内存中的结构以及所占的内存大小。惊不惊喜,意不意外… 在下一篇文章中,我将揭露这其中所不为人知的秘密。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值