java对象内存布局中的基本类型字段排列顺序
java对象内存布局:
mark word(记录hashCode值和锁的标识等等)
class对象指针
- 类字段
- 补齐位
如果是数组对象,2、3之间应该加上 数组长度
布局排列表:
32位jdk 普通对象 |
32位jdk 数组对象 |
64位jdk 未开启指针压缩 普通对象 |
64位jdk 未开启指针压缩 数组对象 |
64位jdk 开启指针压缩 普通对象 |
64位jdk 开启指针压缩 数组对象 |
|
Mark word(m) |
4 |
4 |
8 |
8 |
8 |
8 |
class指针(c) |
4 |
4 |
8 |
8 |
4 |
4 |
数组长度(l) |
0 |
4 |
0 |
8 |
0 |
4 |
类字段(f) |
||||||
补齐位(p) |
单位(byte). 总计 (m+c+l+f+p) % 8 = 0
类字段排列
本文主要简述一下类字段的排列规则。
java对象所占内存大小强制8字节对齐,因此补齐位的存在就是为了补齐8字节,每一个java对象的大小都是8的倍数。(注:本文所说的对象皆为Shallow size,不包含引用对象的大小)
UnSafe
通过 sun.misc.UnSafe#objectFieldOffset(Field) 来获取字段在内存中的偏移量
final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
final Unsafe unsafe = (Unsafe) theUnsafe.get(null);
规则一:(m+c+l) %8 =0
类字段排列规则按照先基本类型,后引用类型,大的在前,小的在后,最后按声明顺序排列。对齐以四字节为单位。下为样例代码:
//以64位jdk 未开启指针压缩 普通对象为例
public class Demo {//32private String str;//16private long l;//24private int i;//30private byte b;//28private short s;public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);final Unsafe unsafe = (Unsafe) theUnsafe.get(null);System.out.println(unsafe.objectFieldOffset(Demo.class.getDeclaredField("l")));System.out.println(unsafe.objectFieldOffset(Demo.class.getDeclaredField("i")));System.out.println(unsafe.objectFieldOffset(Demo.class.getDeclaredField("b")));System.out.println(unsafe.objectFieldOffset(Demo.class.getDeclaredField("s")));System.out.println(unsafe.objectFieldOffset(Demo.class.getDeclaredField("str")));}}
规则二:(m+c+l) % 8 !=0
优先从基本类型字段中找出一个 字段f,使得 (m+c+l+f) %8 =0,如64位jdk开启指针压缩的普通对象mark word+class refence = 12,如果类字段中有int或者float,会优先把这个字段排在前面 ,如果有多个的话,只会选择排在最前列的那个字段,其余字段按照规则一排列;如果没有int或者float,会根据大小的顺序选择 short char byte boolean,选择一个或多个字段大小和为4byte排列,如果只有一个上述字段,那就只排列一个,然后补空位到4byte。
下为样例代码一:
//以64位jdk 开启指针压缩 普通对象为例
public class Demo2 {//16private long l;//12private int i;//24private String str;public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);final Unsafe unsafe = (Unsafe) theUnsafe.get(null);System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("l")));System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("i")));System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("str")));}}
样例代码二:
//以64位jdk 开启指针压缩 普通对象为例
public class Demo2 {//16private long l;//14private byte b;//12private short s;//24private String str;public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");theUnsafe.setAccessible(true);final Unsafe unsafe = (Unsafe) theUnsafe.get(null);System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("l")));System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("b")));System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("s")));System.out.println(unsafe.objectFieldOffset(Demo2.class.getDeclaredField("str")));}}
规则三:继承关系
按照规则一和规则二先排列父类字段,再排列子类字段,父类字段加上mark word + class reference 也会八字节对齐
java对象内存布局中的基本类型字段排列顺序相关推荐
- JOL(java object layout): java 对象内存布局
我们天天都在使用java来new对象,但估计很少有人知道new出来的对象到底长的什么样子?对于普通的java程序员来说,可能从来没有考虑过java中对象的问题,不懂这些也可以写好代码.今天,给大家介绍 ...
- openjdk jol 工具打印 Java 对象内存布局
1.maven 依赖 <dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-cor ...
- JOL(java object layout --java 对象内存布局)
JOL(java object layout --java 对象内存布局) ⚠⚠⚠本文以java普通对象为切入点,分析java的对象内存布局,数组见文末 maven地址
- Java对象内存布局
文章目录 1 场景 2 内存布局图 3 代码验证 3.1 maven依赖 3.2 代码示例 3.3 输出内容 3.4 分析 3.5 补充 4 问题解答 4.1 new空对象占用多少字节 4.2 Jav ...
- Java对象内存布局(JOL)
前言 Java对象的内存布局主要由对象头(Object Header).实例数据(instance data).对齐填充(padding)三部分组成. 对象头:存储对象的基础信息(如锁状态.GC状态. ...
- Java对象内存布局和对象头
Object obj = new Object(); //new 一个对象,占内存多少? 没有实例数据的话,就是16个字节 1.对象的内存布局 在HotSpot虚拟机里,对象在堆内存中的存储布局可以划 ...
- java 对象内存布局_Java--对象内存布局
在HotSpot虚拟机中,对象在内存中的存储布局可以分为3块区域:对象头部.实例数据.对齐填充. 一.对象头部Header的布局 Mark Word Class 指针 在32位系统下,上面两部分各占4 ...
- java对象内存布局及大小
查看虚拟机配置(以hotspot 64bit 虚拟机为例) java -XX:+PrintCommandLineFlags -version 输出结果如下图,表示当前虚拟机的配置信息.每个人的机器可能 ...
- clob类型用java怎么存,运用Java如何存取Oracle中的CLOB类型字段
这是我几年前写的文章了,一直没有发出来.今天给大家分享.大家从这个例子如手吧.这个例子,存和取都很明白了 import java.sql.*; import java.io.*; import ora ...
最新文章
- tomcat启动项目内存溢出问题
- Nginx 教程:基本概念
- 启用轻资产、重运营、降杠杆,红星美凯龙能否瘦成“家得宝”?
- matlab 三角形隶属函数,在MATLAB模糊逻辑工具箱中,常用的隶属函数有:
- How to resolve Unable to load groups error message
- IDEA安装JRebel插件教程
- mysql instead of触发_Instead of触发器
- 数据结构和算法liuyubobo_C++,java算法与数据结构-某课网价值166元实战教程
- Spring Security 安全框架概述 与 快速入门
- 关于缓存使用中的一些看法
- 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(3月5日-3月11日)
- tx2使用远程开机后分辨率不正确
- python函数使用大全_SPSS常见函数及使用方法
- 区块链Baas平台强势来袭,助力企业快速搭建区块链落地项目
- gmx-MMPBSA — error while loading shared libraries: libgfortran.so.3: cannot open shared object file
- ROS创建Publisher理解
- 主数据管理(MDM)与元数据管理
- (三)安装seafile服务器
- C/C++ opencv 计算 LBP特征 包括旋转不变 uniform 圆形邻域
- 关于python接口基础到进阶随笔
热门文章
- guns框架分页实现
- usaco 2.4 bessie come home
- 莫拉蒂出任主席 接替法切蒂重新出山
- 【2022】Rethinking Symbolic Regression Datasets and Benchmarks for Scientific Discovery
- Dlog 替代 NSLog
- 2019年江苏大学885编程大题
- VCS Error-[ XMRE] cross-module reference resolution error
- Java8使用LocalDateTime获取正确的第几周和计算日期最佳方式
- 手机端预览pdf的那些事
- 西建大历年电子与通信工程复试真题_2016年北京理工大学电子与通信工程(882)复试笔试回忆题...