大家都知道,jvm中对象实例存储在堆中,对象的引用存储在栈中,而对象的元数据(类型数据)存储在方法区。在我们进行内存优化的过程中经常需要了解每个对象占用的内存大小。接下来我将介绍对象占用内存大小的计算方式。

Java的对象模型

java是面向对象的语言,每个对象都属于某个类。在HotSpot虚拟机中对象采用的是oop-klass模型。其实原理很简单:就是在方法区中生成一个Class类保存类信息(Klass),包含静态常量、静态方法、字节码、即时编译代码等元数据,而在堆中实例化该类的实例对象(oop),实例对象中保存了指向Class类的指针,这样便构成了oop-klass模型。这样做有一个好处就是:在实现多态时只需要在Class类中保存虚方法表来减少频繁的方法搜索,而实例对象无需保存虚方法表。

每个对象都有一个 mark work 头部,以及一个引用(klass pointer)指向Class类的信息。

  1. 在未开启 UseCompressedOops 的 64 位 JVM 上,对象头有 16 字节大小,即 8 字节的 mark word 和 8 字节的引用。
  2. 在开启 UseCompressedOops 的 64 位机器上,引用成了 4 字节,一共 12 字节。

java对象在内存中模型如下:

Java对象内存占用

对象大小分为:

  1. 自身的大小(Shadow heap size)
  2. 所引用对象的大小(Retained heap size)
class MyClass {int a;Object object;
}

如上图例子所示:myClass 实例创建出来之后,在内存中所占的大小就是 myClass 自身大小(Shadow heap size)。包括类的头部大小以及一个int的大小和一个引用的大小。myClass 中object 成员变量是一个对象引用,这个被引用的对象也占一定大小。myClass 实例所维护的引用的对象所占的大小,称为myClass实例的Retained heap size。我们这里仅讨论如何计算对象自身的大小,引用对象大小的计算方式可依此类推。

java对象内存可分为:头部 + 数据 + 对齐字节
±-----------------±-----------------±----------------- ±--------------+
| mark word | klass pointer | data (opt) | padding |
±-----------------±-----------------±------------------±--------------+

(1)头部大小(mark word + klass pointer)

  1. 在未开启 UseCompressedOops 的 64 位 JVM 上,对象头有 16 字节大小,即 8 字节的 mark word 和8 字节的引用。
  2. 在开启 UseCompressedOops 的 64 位机器上,引用成了 4 字节,一共 12 字节。

(2)数据大小(data)
空对象不包含任何成员变量,其大小即对象头大小。若存在成员成员,为了内存紧凑,成员在内存中的排列和声明的顺序可能不一致,这样才能充分利用内存空间。这是因为在32位系统中,对象大小需要为4byte(32位)的整数倍,而在64位的系统中,对象需要为8byte(64位)的整数倍。如下例子:

class MyClass {byte a;int c;boolean d;long e;Object f;
}

其内存布局为:

值得一提的是,数组对象和普通对象存在一点小区别:数组多一个记录数组长度的 int 类型(4byte

JVM对象占用内存计算相关推荐

  1. Java 中对象占用内存大小计算

    原文地址 mp.weixin.qq.com byte 与 bit bit:位,比特.信息的最小单位,二进制数中的一个位数 (二进制位),其值为"0" 或"1": ...

  2. 由static_cast和dynamic_cast到C++对象占用内存的分析

    static_cast和dynamic_cast是C++的类型转换操作符.编译器隐式执行的任何类型转换都可以由static_cast显式完成,即父类和子类之间也可以利用static_cast进行转换. ...

  3. android图片适配(图片大小与屏幕密度)Bitmap占用内存计算

    目录 概述 dpi 计算公式 dp与px换算公式: android系统适配图片规律: 同名图片放在不同密度的文件夹下,系统选择图片规律 同一张图片,放在不同密度的Drawable文件夹下,ImageV ...

  4. Java 对象占用内存大小

    Java 对象 如果想要了解java对象在内存中的大小,必须先要了解java对象的结构. HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instan ...

  5. java对象占用内存大小?

    一个不包含任何内部成员变量的空Object大约占33byte,若增加成员变量,则增加相应大小的内存占用. 测算方式:设置jvm的堆大小为1m,在堆中不停new不含任何成员变量的OOMObject对象, ...

  6. python查看对象占用内存_『Python』内存分析_List对象内存占用分析

    list声明后结构大体分为3部分,变量名称--list对象(结构性数据+指针数组)--list内容,其中id表示的是list对象的位置, v引用变量名称,v[:]引用list对象,此规则对python ...

  7. meo学习笔记4:C++中对象占用内存情况

    C++中一个对象到底占用多少内存? 1.前言 这个问题对于开发可能不是那么的关注,但是其实在C++相关的题中却经常出现,下面将针对性的记录说明下这个问题 2.直蹦主题 2.1 重要结论 1)非静态成员 ...

  8. Java 获取对象占用内存大小

    1.第一步引入依赖 gradle引入:implementation group: 'org.apache.lucene', name: 'lucene-core', version: '4.0.0'i ...

  9. 2020 idea 查看内存消耗_查看运行时某个java对象占用JVM大小及通过idea查看java的内存占用情况...

    一.如果想看运行时某个java对象占用JVM内存大小,可以先将对象转换成字节类型,然后计算: List bizGroupRelatedEventInfos = bizEventVersionMappe ...

最新文章

  1. Java学习总结:51(对象序列化)
  2. hellowolrd 的系统调用
  3. 分支-03. 三天打鱼两天晒网(Switch…case)
  4. C++中sizeof问题
  5. Thread 小总结
  6. Hbase中的列式表映射到hive的外表
  7. java线程安全问题原因及解决办法
  8. 精通 RPM 之校验篇_检验篇_检测篇
  9. mac php 超时,PHP---Mac上开启php错误提示
  10. 烽火MAS短信服务器配置相关
  11. 好的安排小明(南阳19)(DFS)
  12. Kotlin Weekly 中文周报 —— 102
  13. linux硬盘打开ncq,linux下如何开启ncq
  14. xshell链接相当的慢,怎么解决
  15. 日常开发中,String类中常用的方法
  16. CSS 加粗(css font-weight)
  17. wps表格错开半行_WPS文字制作左右错行表格(运用插入分节符、分栏等功能)
  18. 四、模拟英语四六级答题卡识别阅卷评分
  19. msi和exe安装文件有什么区别
  20. 奥维查看行政边界_【百度地图API】如何获取行政区域的边界? (转载)

热门文章

  1. Linux加密框架crypto crypto_alg|cipher_alg数据结构|AES例子
  2. IT人的好习惯和不良习惯总结
  3. springCloud - 第6篇 - 网关的实现:ZUUL
  4. JS 中去除空格和换行的正则表达式写法
  5. 解决 idea 中 jsp 修改后页面不生效
  6. shader飞线改进版
  7. Java蓝桥杯02——第二题集锦:生日蜡烛、星期一、方格计数、猴子分香蕉
  8. EcmaScript对象克隆之谜
  9. Windows数据库编程接口简介
  10. IIS 部署asp.net Core程序注意事项