java对象内存布局:

  1. mark word(记录hashCode值和锁的标识等等)

  2. class对象指针

  3. 类字段
  4. 补齐位

如果是数组对象,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对象内存布局中的基本类型字段排列顺序相关推荐

  1. JOL(java object layout): java 对象内存布局

    我们天天都在使用java来new对象,但估计很少有人知道new出来的对象到底长的什么样子?对于普通的java程序员来说,可能从来没有考虑过java中对象的问题,不懂这些也可以写好代码.今天,给大家介绍 ...

  2. openjdk jol 工具打印 Java 对象内存布局

    1.maven 依赖 <dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-cor ...

  3. JOL(java object layout --java 对象内存布局)

    JOL(java object layout --java 对象内存布局) ⚠⚠⚠本文以java普通对象为切入点,分析java的对象内存布局,数组见文末 maven地址

  4. Java对象内存布局

    文章目录 1 场景 2 内存布局图 3 代码验证 3.1 maven依赖 3.2 代码示例 3.3 输出内容 3.4 分析 3.5 补充 4 问题解答 4.1 new空对象占用多少字节 4.2 Jav ...

  5. Java对象内存布局(JOL)

    前言 Java对象的内存布局主要由对象头(Object Header).实例数据(instance data).对齐填充(padding)三部分组成. 对象头:存储对象的基础信息(如锁状态.GC状态. ...

  6. Java对象内存布局和对象头

    Object obj = new Object(); //new 一个对象,占内存多少? 没有实例数据的话,就是16个字节 1.对象的内存布局 在HotSpot虚拟机里,对象在堆内存中的存储布局可以划 ...

  7. java 对象内存布局_Java--对象内存布局

    在HotSpot虚拟机中,对象在内存中的存储布局可以分为3块区域:对象头部.实例数据.对齐填充. 一.对象头部Header的布局 Mark Word Class 指针 在32位系统下,上面两部分各占4 ...

  8. java对象内存布局及大小

    查看虚拟机配置(以hotspot 64bit 虚拟机为例) java -XX:+PrintCommandLineFlags -version 输出结果如下图,表示当前虚拟机的配置信息.每个人的机器可能 ...

  9. clob类型用java怎么存,运用Java如何存取Oracle中的CLOB类型字段

    这是我几年前写的文章了,一直没有发出来.今天给大家分享.大家从这个例子如手吧.这个例子,存和取都很明白了 import java.sql.*; import java.io.*; import ora ...

最新文章

  1. tomcat启动项目内存溢出问题
  2. Nginx 教程:基本概念
  3. 启用轻资产、重运营、降杠杆,红星美凯龙能否瘦成“家得宝”?
  4. matlab 三角形隶属函数,在MATLAB模糊逻辑工具箱中,常用的隶属函数有:
  5. How to resolve Unable to load groups error message
  6. IDEA安装JRebel插件教程
  7. mysql instead of触发_Instead of触发器
  8. 数据结构和算法liuyubobo_C++,java算法与数据结构-某课网价值166元实战教程
  9. Spring Security 安全框架概述 与 快速入门
  10. 关于缓存使用中的一些看法
  11. 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(3月5日-3月11日)
  12. tx2使用远程开机后分辨率不正确
  13. python函数使用大全_SPSS常见函数及使用方法
  14. 区块链Baas平台强势来袭,助力企业快速搭建区块链落地项目
  15. gmx-MMPBSA — error while loading shared libraries: libgfortran.so.3: cannot open shared object file
  16. ROS创建Publisher理解
  17. 主数据管理(MDM)与元数据管理
  18. (三)安装seafile服务器
  19. C/C++ opencv 计算 LBP特征 包括旋转不变 uniform 圆形邻域
  20. 关于python接口基础到进阶随笔

热门文章

  1. guns框架分页实现
  2. usaco 2.4 bessie come home
  3. 莫拉蒂出任主席 接替法切蒂重新出山
  4. 【2022】Rethinking Symbolic Regression Datasets and Benchmarks for Scientific Discovery
  5. Dlog 替代 NSLog
  6. 2019年江苏大学885编程大题
  7. VCS Error-[ XMRE] cross-module reference resolution error
  8. Java8使用LocalDateTime获取正确的第几周和计算日期最佳方式
  9. 手机端预览pdf的那些事
  10. 西建大历年电子与通信工程复试真题_2016年北京理工大学电子与通信工程(882)复试笔试回忆题...