【Java对象解析】不得不了解的对象头

一个Java对象到底占用多大内存?

JVM源码分析之java对象头实现

java对象在内存中的结构(转帖)

一个Java对象到底占多大内存?

在Hotspot JVM中,32位机器下,Integer对象的大小是int的几倍?

我们都知道在Java语言规范已经规定了int的大小是4个字节,那么Integer对象的大小是多少呢?

要知道一个对象的大小,那么必须需要知道对象在虚拟机中的结构是怎样的,来看看Hotspot中对象在内存中的结构

从上面的这张图里面可以看出,对象在内存中的结构主要包含以下几个部分:

Mark Word:   对象的Mark Word部分占4个字节,其内容是一系列的标记位,比如轻量级锁的标记位,偏向锁标记位等等。
Class对象指针:Class对象指针的大小也是4个字节,其指向的位置是对象对应的Class对象(其对应的元数据对象)的内存地址
对象实际数据: 这里面包括了对象的所有成员变量,其大小由各个成员变量的大小决定,
比如:byte和boolean是1个字节,short和char是2个字节,int和float是4个字节,long和double是8个字节,reference是4个字节
对齐: 最后一部分是对齐填充的字节,按8个字节填充。

根据上面的图,那么我们可以得出Integer的对象的结构如下:

Integer只有一个int类型的成员变量value,所以其对象实际数据部分的大小是4个字节,

然后再在后面填充4个字节达到8字节的对齐,所以可以得出Integer对象的大小是16个字节。

因此,我们可以得出Integer对象的大小是原生的int类型的4倍

关于对象的内存结构,需要注意数组的内存结构和普通对象的内存结构稍微不同,

因为数据有一个长度length字段,所以在对象头后面还多了一个int类型的length字段,占4个字节,接下来才是数组中的数据,如下图:

1,HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:

对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。 

2,HotSpot虚拟机的对象头(Object Header)包括两部分信息,

2,1,第一部分用于存储对象自身的运行时数据,

如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,
这部分数据的长度在32位和64位的虚拟机(暂 不考虑开启压缩指针的场景)中分别为32个和64个Bits,官方称它为“Mark Word”。

对象需要存储的运行时数据很多,其实已经超出了32、64位Bitmap结构所能记录的限度,

但是对象头信息是与对象自身定义的数据无关的额 外存储成本,

考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。

例如在32位的HotSpot虚拟机 中对象未被锁定的状态下

Mark Word的32个Bits空间中的25Bits用于存储对象哈希码(HashCode),4Bits用于存储对象分代年龄,2Bits用于存储锁标志 位,1Bit固定为0,

在其他状态(轻量级锁定、重量级锁定、GC标记、可偏向)下对象的存储内容如下表所示。

2,2,对象头的另外一部分是类型指针,

即是对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说查找对象的元数据信息并不一定要经过对象本身。

另外,如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,

因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小。

java对象的结构的更多相关文章

  1. JAVA 对象内存结构

    JAVA对象内存结构 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 对象头 markWo ...

  2. Synchronized加锁、锁升级和java对象内存结构

    首先了解一下JMM中定义的内存操作: 一个线程操作数据时候都是从主内存(堆内存)读取到自己工作内存(线程私有的数据区域)中再进行操作.对于硬件内存来说,并没有工作内存和主内存的区分,这都是java内存 ...

  3. [Java基础] Java对象内存结构

    转载地址:http://www.importnew.com/1305.html 原文于2008年11月13日 发表, 2008年12月18日更新:这里还有一篇关于Java的Sizeof运算符的实用库的 ...

  4. (四)java对象的结构和对象的访问定位

    在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 一. 对象头 HotSpot虚拟机的对象 ...

  5. Ehcache计算Java对象内存大小

    在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...

  6. 一个 Java 对象到底有多大?

    阅读本文大概需要 2.8 分钟. 出处:http://u6.gg/swLPg 编写 Java 代码的时候,大多数情况下,我们很少关注一个 Java 对象究竟有多大(占据多少内存),更多的是关注业务与逻 ...

  7. paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象)

    paip.提升性能----java 无锁结构(CAS, Atomic, Threadlocal, volatile, 函数式编码, 不变对象) 1     锁的缺点 2     CAS(Compare ...

  8. java对象在内存中的结构

    在HotspotJVM中,32位机器下,Integer对象的大小是int的几倍? 我们都知道在java语言规范已经规定了int的大小是4个字节,那么Integer对象的大小是多少呢?要知道一个对象的大 ...

  9. java中的进程与线程及java对象的内存结构【转】

    原文地址:http://rainforc.iteye.com/blog/2039501   1.实现线程的三种方式:   使用内核线程实现     内核线程(Kernel Thread, KLT)就是 ...

随机推荐

  1. MySql 几个小技巧

    分页查看: 在 mysql 环境下,执行命令: pager more,之后的结果分屏了. 简明扼要地查看表结构: describe table_name

  2. [Selenium]验证点了某个Button之后无反应

    期望:点了某个Button,无反应 问题:怎么去验证无反应 WebElement webElement = page.getICORemove(); SeleniumUtil.hover(page.g ...

  3. js技巧汇总

    1.window.open()打开一个子页面,在子页面关闭时刷新父页面 子页面关闭事件代码:window.opener.location.href=window.opener.location.hre ...

  4. python协程函数、递归、匿名函数与内置函数使用、模块与包

    目录: 协程函数(yield生成器用法二) 面向过程编程 递归 匿名函数与内置函数的使用 模块 包 常用标准模块之re(正则表达式) 一.协程函数(yield生成器用法二) 1.生成器的语句形式 a. ...

  5. 2018.10.13 bzo1934: [Shoi2007]Vote 善意的投票(最小割)

    传送门 最小割定义题. 按照题意建边就行了. 考虑把冲突变成把aaa选入不与自己匹配的集合所需要付出的代价. 然后跑最小割就行了. 代码: #include<bits/stdc++.h> ...

  6. 2018.07.04 BZOJ 2618 Cqoi2006凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec Memory Limit: 128 MB Description 逆时针给出n个凸多边形的顶点坐标,求它们交的面积.例如n ...

  7. Python安装setuptools遇到的MARKER_EXPR错误

    # python setup.py install Traceback (most recent call last):   File "setup.py", line 11, i ...

  8. C/C++的Name Mangling

    C语言 函数 1.void __CALLTYPE f();2.int __CALLTYPE f();3.int __CALLTYPE f(int);4.double __CALLTYPE f(int, ...

  9. 3D空间中射线与三角形的交叉检测算法【转】

    引言 射线Ray,在3D图形学中有很多重要的应用.比如,pick操作就是使用射线Ray来实现的,还有诸如子弹射线的碰撞检测等等都可以使用射线Ray来完成.所以,在本次博客中,将会简单的像大家介绍下,如 ...

  10. 用.netcore写一个简单redis驱动,调试windows版本的redis.平且给set和get命令添加参数.

    1. 下载windows版本的redis 2.开发环境vs2017  新建一个 .net core控制台. private static Socket socket = new Socket(Addr ...