java对象内存结构分析与大小计算
java对象内存结构
Java对象保存在堆中时,由三部分组成:
对象头(object header):包括了关于堆对象的布局、类型、GC状态、同步状态和标识哈希码的基本信息。所有java对象都有一个共同的对象头格
实例数据(Instance Data):主要是存放类的数据信息,父类的信息,对象字段属性信息。
数据长度(array length):记录了数组的长度(只有对象是数组时才有这个结构)。
对齐填充(Padding):为了字节对齐成的8倍数,填充的数据,不是必须的。
什么是对象头?
我们可以在Hotspot官方文档中找到它的描述。从中可以发现,它是Java对象和虚拟机内部对象都有的共同格式,由两个字(计算机术语)组成。另外,如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数组的元数据中无法确定数组的大小。
它里面提到了对象头由两个字组成,这两个字分别是 mark word和 klass pointer。
什么是mark word
用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等。
Mark Word在32位JVM中的长度是32bit,在64位JVM中长度是64bit。
虽然它们在不同位数的JVM中长度不一样,但是基本组成内容是一致的。
锁标志位(lock):区分锁状态,11时表示对象待GC回收状态, 只有最后2位锁标识(11)有效。
biased_lock:是否偏向锁,由于正常锁和偏向锁的锁标识都是 01,没办法区分,这里引入一位的偏向锁标识位。
分代年龄(age):表示对象被GC的次数,当该次数到达阈值的时候,对象就会转移到老年代。
对象的hashcode(hash):运行期间调用System.identityHashCode()来计算,延迟计算,并把结果赋值到这里。当对象加锁后,计算的结果31位不够表示,在偏向锁,轻量锁,重量锁,hashcode会被转移到Monitor中。
偏向锁的线程ID(JavaThread):偏向模式的时候,当某个线程持有对象的时候,对象这里就会被置为该线程的ID。 在后面的操作中,就无需再进行尝试获取锁的动作。
epoch:偏向锁在CAS锁操作过程中,偏向性标识,表示对象更偏向哪个锁。ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针。当锁获取是无竞争的时,JVM使用原子操作而不是OS互斥。这种技术称为轻量级锁定。在轻量级锁定的情况下,JVM通过CAS操作在对象的标题字中设置指向锁记录的指针。ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针。如果两个不同的线程同时在同一个对象上竞争,则必须将轻量级锁定升级到Monitor以管理等待的线程。在重量级锁定的情况下,JVM在对象的ptr_to_heavyweight_monitor设置指向Monitor的指针。
Klass Pointer
即类型指针,是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
实例数据
如果对象有属性字段,则这里会有数据信息。如果对象无属性字段,则这里就不会有数据。根据字段类型的不同占不同的字节,例如boolean类型占1个字节,int类型占4个字节等等;
对齐填充
对象可以有对齐数据也可以没有。默认情况下,Java虚拟机堆中对象的起始地址需要对齐至8的倍数。如果一个对象用不到8N个字节则需要对其填充,以此来补齐对象头和实例数据占用内存之后剩余的空间大小。如果对象头和实例数据已经占满了JVM所分配的内存空间,那么就不用再进行对齐填充了。
所有的对象分配的字节总SIZE需要是8的倍数,如果前面的对象头和实例数据占用的总SIZE不满足要求,则通过对齐数据来填满。
为什么要对齐数据?
字段内存对齐的其中一个原因,是让字段只出现在同一CPU的缓存行中。如果字段不是对齐的,那么就有可能出现跨缓存行的字段。也就是说,该字段的读取可能需要替换两个缓存行,而该字段的存储也会同时污染两个缓存行。这两种情况对程序的执行效率而言都是不利的。其实对其填充的最终目的是为了计算机高效寻址。
java对象大小的计算(我是64位计算机 JDK8)
maven 引入如下jar包
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.16</version></dependency>
demo code
public class ObjectTest {public static void main(String[] args) {System.out.println("****************没属性**********************");testOne testOne = new testOne();System.out.println(ClassLayout.parseInstance(testOne).toPrintable());System.out.println("****************有属性**********************");testTwo testTwo = new testTwo();System.out.println(ClassLayout.parseInstance(testTwo).toPrintable());System.out.println("****************有数组**********************");testTwo[] testTwoArr = new testTwo[]{new testTwo(),new testTwo()};System.out.println(ClassLayout.parseInstance(testTwoArr).toPrintable());}
}class testOne{}class testTwo{private int a;}
结果含义
OFF : 偏移地址,单位字节;
SZ :占用的内存大小,单位为字节;
TYPE DESCRIPTION : 类型描述,
其中object header:mark为对象头的markword;
其中object header:class为对象头的klass pointer;
其中 object alignment gap 为对齐填充
其中array length 为数组长度
由于jdk默认开启了指针压缩。
所以我们能看到object header: class 变成了4个字节。 对象头占了12个字节
可以通过配置vm参数开启关闭指针压缩,-XX:-UseCompressedOops。这时候对象头变成了16个字节****************无属性**********************
com.tongji.testOne object internals:
OFF SZ TYPE DESCRIPTION VALUE0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)8 4 (object header: class) 0xf800c24412 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
1.对象头mark 8个字节+对象头 klass pointer 4个字节=12字节
2.由于12不是8的整数被所以需要把12填充到8的倍数
3.最接近12的能被整除的是16故需要填充4个字节 16-12=4字节。****************有属性**********************
com.tongji.testTwo object internals:
OFF SZ TYPE DESCRIPTION VALUE0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)8 4 (object header: class) 0xf800cfce12 4 int testTwo.a 0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
1.对象头mark 8个字节+对象头 klass pointer 4个字节=12字节
2.类中int 占4个字节
3.12+4=16个字节 能被8整除故不需要填充****************数组**********************
[Lcom.tongji.testTwo; object internals:
OFF SZ TYPE DESCRIPTION VALUE0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)8 4 (object header: class) 0xf800d0dc12 4 (array length) 212 4 (alignment/padding gap) 16 8 com.tongji.testTwo testTwo;.<elements> N/A
Instance size: 24 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total1.对象头mark 8个字节+对象头 klass pointer 4个字节=12字节
2.array length 占4个字节
3.elements 占8个字节
4.12+4+8=24字节
GC年龄为啥最大是15?大家猜猜是为啥!
看到前面的对象头的mark word 大家肯定都知道了 GC年龄无论在32位还是64位计算机只占了4位其最大值也就是 1111(二进制)=2^4-1=15.
平常常用的hashCode藏在哪里?
相关文章:
java对象内存结构分析与大小计算
java对象内存结构Java对象保存在堆中时,由三部分组成:对象头(object header):包括了关于堆对象的布局、类型、GC状态、同步状态和标识哈希码的基本信息。所有java对象都有一个共同的对象头格实例数据(Insta…...
RabbitMQ学习(七):交换器
〇、前言在之前的内容中,我们创建了一个工作队列。我们假设的是工作队列背后,每个任务都恰好交付给一个消 费者(工作进程)。在今天的内容中,我们将做一些完全不同的事情——我们将消息传达给多个消费者。这种模式 称为 “发布/订阅”。为了说…...
cmd命令大全
文章目录变量输入输出逻辑命令符控制语句函数注释变量 在批处理中,变量全部是弱类型的,通常可以当做字符串处理 1.初始化定义 set varthis a var 2.获取变量值 %var% 3.链接 set varcat%var1%%var2% 4.截取 %var:~n,m% n是起点,m是长度&…...
Git的使用方法(保姆级)
一、安装git二、创建凭据 ①打开电脑的凭据管理器git:https://gitee.com是固定写法用户名、密码是你创建gitee的用户名、密码三、在gitee中创建一个仓库四、项目提交到仓库的方法①选择一个项目交由git管理按照步骤一中召唤小黑窗口输入 git init 就可以出现.git文件夹②右键选…...
TypeScript 学习之泛型
泛型使用 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型。就需要使用泛型。使用泛型就不会丢失类型信息,使用any会丢失类型信息。 function identity<T>(arg: T): T {return arg; }identity 添加了类型变量T, T 捕获用户传入的类型…...
新手学习node.js基础,node.js安装过程,node.js运行环境及javascript运行环境.
学习node.js1.什么是node.js?2.node.js中的javaScript运行环境3.node.js可以做什么?4. node.js学习思路5.node.js环境的安装6.如何在node.js中执行JavaScript代码1.什么是node.js? node.js是一个基于Chrome v8 引擎的JavaScript运行环境(后端) node.js官网 &…...
Maven的安装步骤(保姆级安装教程)
一、安装本地Maven 选择你需要的maven版本下载:官网下载传送门 我使用的是3.6.1版本:maven-3.6.1-bin.zip 二、安装 把下载好的maven压缩包解压到一个没有中文,空格或其他特殊字符的文件夹,如: 三、配置环境变量…...
Axure教程(一)——线框图与高保真原型图制作
前面我们学习了制作网页的技能,从这里开始我们来学习前端必备技能,就是用Axure来制作原型图,一方面我们能提前绘制出我们所需的页面,这在我们开发的时候能节省大量的时间,另一方面我们能通过给用户进行体验从而能够发现…...
wholeaked:一款能够追责数据泄露的文件共享工具
关于wholeaked wholeaked是一款功能强大的文件共享工具,该工具基于go语言开发,可以帮助广大系统管理员和安全研究人员在组织发生数据泄露的时候,迅速找出数据泄露的“始作俑者”。 wholeaked可以获取被共享的文件信息以及接收人列表&#x…...
动态规划——股票问题全解
引入 股票问题是一类动态问题,我们需要对其状态进行判定分析来得出答案 但其实,我们只需要抓住两个点,持有和不持有,在这两种状态下分析问题会简单清晰许多 下面将会对各个问题进行分析讲解,来解释什么是持有和不持…...
想做游戏开发要深入c/c++还是c#?
根据题主描述提三点建议: 先选择一个语言、选择一个引擎能入行确保精通一个及已入行的情况下,技多不压身不必想日后的”退而求其次“,现在的事情还没有开始做就想以后,太过虚无及功利了 下面是这三点的详细说明: 【选…...
【JMeter】【Mac】如何在Mac上打开JMeter
平常我们在Windows电脑里打开JMeter,只要双击JMeter.bat即可打开,那我换了Mac后,该怎么打开JMeter呢 一、命令行打开JMeter 1、打开JMeter路径 cd /Users/work/apache-jmeter-5.2/bin 2、运行JMeter sh jmeter 3、如果涉及到一些权限无…...
JAVA面试八股文一(并发与线程)
并发的三大特性原子性:cpu在执行过程不可以暂停然后再调度,不可以中断,要不全部执行完,要不全部不执行。可见性:当多个线程访问同一个变量时,一个线程改变了这个变量的值,其他线程能够立即看到修…...
C语言二级指针
目录一、1. 指针的作用2.二级指针3. 为什么要用二级指针一、 1. 指针的作用 内存的存储区就像一池湖水,数据就像池水里面的鱼,如果不用内存寻址的方式,那么当你找某个特定数据的时候,就相当于在一池湖水里找某一条叫做“张三”的…...
[java-面试]初级、中级、高级具备的技术栈和知识点
🌟1.java初级1. Java基础知识:语法、包装类、泛型、数据结构和继承,以及基础API。2. Java开发工具:如Eclipse,NetBeans,Maven等。3. Java Web开发技术:如Servlet,JSP,Str…...
「5」线性代数(期末复习)
🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀 目录 第四章 向量组的线性相关性 &5)向量空间 第五章 相似矩阵及二次型 &a…...
记一次20撸240的沙雕威胁情报提交(2019年老文)
0x01 起因 这是一篇沙雕文章,没什么技术含量,大家娱乐一下就好 前几个月,我的弟弟突然QQ给我发来了一条消息,说要买个QQ飞车的cdk,我作为一个通情达理的好哥哥,自然不好意思回绝,直接叫他发来…...
佳能镜头EOS系统EF协议逆向工程(三)解码算法
目录 数据结构 解码算法 解码效果 这篇文章基于上两篇文章继续, 佳能镜头EOS系统EF协议逆向工程(一)转接环电路设计_佳能ef自动对焦协议_岬淢箫声的博客-CSDN博客本文属于专栏——工业相机。此专栏首先提供我人工翻译的法语文档部分&…...
搞互联网吧,线下生意真不是人干的
搞互联网吧,线下生意真不是人干的 应该是正月初几里吧,好巧不巧的被迫去参加了一下我们初中同学的聚会。其实毕业这么多年,无论大学,高中还是中学,类似的聚会我都是能躲则躲,有特别想见的同学也都是私下单…...
MySQL性能调优与设计——MySQL中的索引
MySQL中的索引 InnoDB存储引擎支持以下几种常见索引:B树索引、全文索引、哈希索引,其中比较关键的是B树索引。 B树索引 InnoDB中的索引自然也是按照B树来组织的,B树的叶子节点用来存放数据。 聚集索引/聚簇索引 InnoDB中使用了聚集索引&…...
这5个代码技巧,让我的 Python 加速了很多倍
Python作为一种功能强大的编程语言,因其简单易学而受到很多初学者的青睐。它的应用领域又非常广泛:科学计算、游戏开发、爬虫、人工智能、自动化办公、Web应用开发等等。 而在数据科学领域中,Python 是使用最广泛的编程语言,并且…...
Sphinx+Scws 搭建千万级准实时搜索应用场景详解
目标: 一、搭建准确的千万级数据库的准实时搜索(见详情) 二、实现词语高亮(客户端JS渲染,服务器端渲染,详见7.3) 三、实现搜索联想(输入框onchange,ajax请求搜索,取10条在…...
kafka缩容后,使用tcpdump抓包找到还在连接的用户
1、使用tcpdump抓包监控端口9092 tcpdump src port 9092 16:23:27.680835 IP host01.XmlIpcRegSvc > 192.168.168.1.36199: Flags [R.], seq 0, ack 1493547965, win 0, length 0 16:23:27.681877 IP host01.XmlIpcRegSvc > 192.168.168.2.50416: Flags [R.], seq 0, ac…...
Spring
Spring Spring 是什么? Spring 是于 2003 年兴起的一个轻量级的,IOC 和 AOP 的 Java 开发框架,它 是为了简化企业级应用开发而生的。 Spring有几大特点如下 轻量级的 Spring 框架使用的 jar 都比较小,一般在 1M 以下或者几百 kb。Spring 核 心功能…...
vue2版本《后台管理模式》(中)
文章目录前言一、创建一个文件夹 utils 里面新增一个 setToken.js 文件(设置token验证)二 、创建一个api文件夹 新增 service.js (axios拦截器)三、在api文件夹里 新增一个 api.js 来接收数据(把api封装哪里需要某项数据直接引入就…...
网络游戏开发-服务器篇
1.网络 网络分为弱联网和强联网。 1.弱联网 弱联网是客户端连接到服务端发送一个请求,然后由服务端回应一个内容,这是单向传输的方式,服务端是无法主动给客户端发送消息的,服务端相应请求之后会自动关闭连接。 缺点:传输采用明文,通过抓包可以看到明文信息,安全性不太…...
智慧校园源码:电子班牌,支持手机移动端以及web端对班牌设备的管控
▶ 智慧校园系统有源码,有演示! (电子班牌)设备管理: 1、 管理员查看全校电子班牌设备信息:含有(班级信息、软件版本、设备型号、开关机信息、班牌截屏信息、教室编号、设备ID、设备描述、在线状态、离线状…...
研报精选230216
目录 【行业230216东吴证券】环保行业月报:2023M1环卫新能源渗透率大增至11.91%,上海地区渗透率高达77%【行业230216国元证券】国元新食饮:一图君:22年白酒产量:同降6.2%【行业230216浙商证券】农林牧渔点评报告&#…...
在华为MateBook Ego的arm windows 11上安装hyper-V虚拟机
入手一台华为matebook Ego的笔记本,由于想要测试一些arm的驱动功能,经常会把系统搞蓝屏,于是想安装一个虚拟机,于是试了vmware ,visual-box,由于本机是arm架构上面两个软件都无法进行正常安装,可能是由于有…...
OpenCV Canny边缘检测
本文是OpenCV图像视觉入门之路的第13篇文章,本文详细的介绍了Canny边缘检测算子的各种操作,例如:Canny算子进行边缘检测等操作。 Canny函数是OpenCV中用于执行边缘检测的函数之一,其参数包括: threshold1:…...
独山县哪里有做网站的/百度收录api怎么提交
思路:题意抽象出来就是,找到一个最小边权值为d,删除大于d的边,使得剩下的联通块的个数不大于k个。这个题我们可以发现d越大连通块越少,d与连通块个数成单调函数。 那么可以二分d,然后dfs/bfs求联通块个数判…...
养生门户网站源码/抖音竞价推广怎么做
红黑树(英语:Red–black tree)是一种自平衡二叉查找树,典型用途是实现关联数组。 红黑树的操作有着良好的最坏情况运行时间,并且在实践中高效:它可以在O(log n)时间内完成查找、插入和删除,这里…...
直销网站建设公司/seo流量是什么
基于随机的共识共识是一种强大的方法,可以产生强有力的支持和决策的共享所有权。 但是应用可能会很困难,如果使用不当,则会产生中等的结果。 这篇文章可帮助您利用共识来做出成功的产品决策。 它说明了何时以及如何使用它,并讨论了…...
免费b2b网站排名/360免费建站
hp m425dn打印机ADC进纸器复印或者扫描全黑。平板复印文档正常。解决方法:设置-服务-恢复默认值后解决。转载于:https://blog.51cto.com/tianhui/1695334...
网站关键词推广哪家好/搜索引擎营销的主要方式有
2019独角兽企业重金招聘Python工程师标准>>> 一.系统目录结构 1.linux系统目录图 2.目录介绍 /bin:bin是Binary的缩写,该目录下存放的是最常用的命令。/boot:该目录下存放的是启动Linux时使用的一些核心文件,包括一些连…...
深圳百姓网/优化网站内容
1.自定义标签 *步骤: **编写一个实现Tag接口的Java类,把页面中的java代码移到这个java类中(标签处理器类) **编写标签库描述符(tld)文件,在tld文件中把标签处理器描述成一个标签。 *作用&…...