附 Java对象内存布局
注意:本篇博客,主要参考自《深入理解Java虚拟机(第二版)》
1、对象在内存中存储的布局分为三块
- 对象头
- 存储对象自身的运行时数据:Mark Word(在32bit和64bit虚拟机上长度分别为32bit和64bit),包含如下信息:
- 对象hashCode
- 对象GC分代年龄
- 锁状态标志(轻量级锁、重量级锁)
- 线程持有的锁(轻量级锁、重量级锁)
- 偏向锁相关:偏向锁、自旋锁、轻量级锁以及其他的一些锁优化策略是JDK1.6加入的,这些优化使得Synchronized的性能与ReentrantLock的性能持平,在Synchronized可以满足要求的情况下,优先使用Synchronized,除非是使用一些ReentrantLock独有的功能,例如指定时间等待等。
- 类型指针:对象指向类元数据的指针(32bit-->32bit,64bit-->64bit(未开启压缩指针),32bit(开启压缩指针))
JVM通过这个指针来确定这个对象是哪个类的实例(根据对象确定其Class的指针)
- 实例数据:对象真正存储的有效信息
- 对齐填充
- JVM要求对象的大小必须是8的整数倍,若不是,需要补位对齐
2、注意
- Mark Word具有非固定的数据结构,以便在极小的空间内存储尽量多的信息
- 如果对象是一个数组,对象头必须有一块儿用于记录数组长度的数据。JVM可以通过Java对象的元数据确定对象长度,但是对于数组不行。
- 对于对象头长度而言
- 32bit虚拟机一定是32bit+32bit,即8字节
- 64bit虚拟机若没有开启了压缩指针,是64bit+64bit,即16字节,若开启了压缩指针,是64bit+32bit,即12字节(不是8bit的倍数)
- -XX:+UseCompressedOops:开启压缩指针
- 在《深入理解Java虚拟机(第二版)》中,说对象头是8字节或16字节,不知道是不是有误,自己的系统不是64bit,没有测试
- 基本数据类型与对应包装类的选用

在实际使用中,我们会根据字节数较小的一方来选用基本数据类型还是使用其包装类。
- 在《第二章 JVM内存分配 》中说过,实际对象所占的内存大小在类加载完成后就可以知道了,具体是怎样计算的,可以参看这一篇文章http://www.importnew.com/14948.html
附 Java对象内存布局的更多相关文章
- Java对象内存布局
本文转载自Java对象内存布局 导语 首先直接抛出问题 Unsafe.getInt(obj, fieldOffset)中的fieldOffset是什么, 类似还有compareAndSwapX(obj ...
- 图文详解Java对象内存布局
作为一名Java程序员,我们在日常工作中使用这款面向对象的编程语言时,做的最频繁的操作大概就是去创建一个个的对象了.对象的创建方式虽然有很多,可以通过new.反射.clone.反序列化等不同方式来创建 ...
- Java单个对象内存布局.md
我们在如何获取一个Java对象所占内存大小的文章中写了一个获取Java对象所占内存大小的工具类(ObjectSizeFetcher),那么接下来,我们使用这个工具类来看一下Java中各种类型的对象所占 ...
- Java虚拟机14:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- Java虚拟机18:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- Ehcache计算Java对象内存大小
在EHCache中,可以设置maxBytesLocalHeap.maxBytesLocalOffHeap.maxBytesLocalDisk值,以控制Cache占用的内存.磁盘的大小(注:这里Off ...
- JAVA 对象内存结构
JAVA对象内存结构 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 对象头 markWo ...
- [Java基础] Java对象内存结构
转载地址:http://www.importnew.com/1305.html 原文于2008年11月13日 发表, 2008年12月18日更新:这里还有一篇关于Java的Sizeof运算符的实用库的 ...
- java对象内存大小评估
Java对象的内存布局:对象头(Header).实例数据(Instance Data)和对齐填充(Padding).无论是32位还是64位的HotSpot,使用的都是8字节对齐.也就是说每个java对 ...
随机推荐
- thinkphp 5.0如何实现自定义404(异常处理)页面
404页面是客户端在浏览网页时,由于服务器无法正常提供信息,或是服务器无法回应,且不知道原因所返回的页面.404承载着用户体验与SEO优化的重任.404页面通常为用户访问了网站上不存在或已删除的页面, ...
- IAR搭建unity框架
1. 新建工程 2. 增加组 unit,并加入相应源码 3. 增加需要测试的API源文件 4. 编写相应的测试用例 编译,download and debug view->TerminalIO ...
- win10 远程桌面远程电脑时每次要输入密码及身份验证错误,要求的函数不受支持问题解决
解决以前每次远程时能能记住密码,更新系统补丁后现在每次登录要输入密码了及远程时提示身份验证错误,要求的函数不受支持问题 解决方法一.卸载更新安装的新补丁,远程桌面正常,能记住密码 解决方法二.修改注册 ...
- maven 发布jar包到远程仓库
有的时候我们需要发布一些自己写的相关jar包到maven私服,供项目组使用. 首先在setting.xml文件添加,这里 注意 要保证该账户有发布的权限 <servers> <ser ...
- [leetcode greedy]455. Assign Cookies
Assume you are an awesome parent and want to give your children some cookies. But, you should give e ...
- 重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using passwor
一般这个错误是由密码错误引起,解决的办法自然就是重置密码. 假设我们使用的是root账户. 1.重置密码的第一步就是跳过MySQL的密码认证过程,方法如下: #vim /etc/my.cnf(注:wi ...
- 【二分答案】Google Code Jam Round 1A 2018
题意:有R个机器人,去买B件商品,有C个收银员,每个收银员有能处理的商品数量上限mi,处理单件商品所需的时间si,以及最后的装袋时间pi. 每个收银员最多只能对应一个机器人,每个机器人也最多只能对应一 ...
- java线程系列文章之一(线程的安全性)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7421217,转载请注明. 当我们查看JDK API的时候,总会发现一些类 ...
- linux_jdk_mysql_tomcat
1 linux下安装jdk的步骤: 0. 查找原有的jdk: rpm -qa | grep java 删除原有的jdk: rpm -e --nodeps java-1.7.0-openjdk-1.7. ...
- Java Threads 多线程10分钟参考手册
1 同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通常把这 ...