java内存使用——如何计算一个Java对象占用的字节数
java内存使用——如何计算一个Java对象占用的字节数
清风傲剑 发表于3年前
java内存使用——如何计算一个Java对象占用的字节数
  • 发表于 3年前
  • 阅读 71
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 在开发中,作为开发人员必须了解使用某语言创建对象大概有多少字节,在内存有限的情况下,可以撑住多少同时访问,而且在编码过程中,不要过分依赖GC,GC不是万能的。借鉴它人英译的一篇博客来详细了解下如何计算一个Java对象占用的字节数

原文地址:点击打开链接 ,翻译有出入之处,请以原文为准

本文中,我们讨论一个问题:如何计算(或者说,估算)一个Java对象占用的内存数量?

通常,我们谈论的堆内存使用的前提是以“一般情况”为背景的。不包括下面两种情形:

  1. 某些情况下,JVM根本就没有把Object放入堆中。例如:原则上讲,一个小的thread-local对象存在于栈中,而不是在堆中。

  2. 被Object占用内存的大小依赖于Object的当前状态。例如:Object的同步锁是否生效,或者,Object是否正在被回收。

我们先来看看在堆中单个的Object长什么样子

在堆中,每个对象由四个域构成(A、B、C 和 D),下面我们逐个解释一下:

  1. A:对象头,占用很少的字节,表述Object当前状态的信息

  2. B:基本类型域占用的空间(原生域指 int、boolean、short等)

  3. C:引用类型域占用的空间(引用类型域指 其他对象的引用,每个引用占用4个字节)

  4. D:填充物占用的空间(后面说明什么是填充物)

下面我们对A、B、C 和 D 逐一解释

A:对象头

  内存中,每个对象占用的总空间不仅包含对象内声明的变量所需要的空间,还包括一些额外信息,比如:对象头 和 填充物。“对象头”的作用是用来记录一个对象的实例名字、ID 和 实例状态(例如,当前实例是否“可到达”,或者当前锁的状态等等)。

在当前的JVM版本中(Hotspot),“对象头”占用的字节数如下:

  1. 一个普通对象,占用8 bytes

  2. 数组,占用 12 bytes,包含普通对象的 8 bytes + 4 bytes(数组长度)

B:基本类型

boolean、byte 占用 1 byte,char、short 占用 2 bytes,int、float 占用 4 bytes,long、double 占用 8 bytes

C:引用类型

  每个引用类型占用 4 bytes

D:填充物

在Hotspot中,每个对象占用的总空间是以8的倍数计算的,对象占用总空间(对象头+声明变量)不足8的倍数时候,自动补齐。而,这些被填充的空间,我们可以称它为“填充物”。我们看下具体实例:

  1. 一个空对象(没有声明任何变量)占用 8 bytes -- > 对象头 占用 8 bytes

  2. 只声明了一个boolean类型变量的类,占用 16 bytes --> 对象头(8 bytes) + boolean (1 bytes) + 填充物(7 bytes)

  3. 声明了8个boolean类型变量的类,占用 16 bytes --> 对象头(8 bytes) + boolean (1 bytes) * 8

 

共有 人打赏支持
粉丝 29
博文 75
码字总数 40365
×
清风傲剑
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: