当前位置: 首页 > news >正文

JVM对象内存结构

1对象内存结构说明

注意:

如果对象数组对象对象头后面4字节存储数组长度

1.1对象

对象头分为Mark WordClass Pointer两部分

Mark Word对象基础信息

  • 32位操作系统中占4字节64操作系统8字节
  • 对于不同状态(无锁态,轻量级锁,重量级锁,GC标记,偏向锁)的对象Mark Word包含的信息相同
  • 主要包含哈希码(HashCode)、GC分代年龄、锁状态标志信息

Klass Pointer类元数据指针

  • 32位操作系统中占4字节
  • 64位操作系统中占8字节,开启指针压缩时占4字节
  • 表明对象属于哪个类型
  • 元数据存在方法区记录这个哪些属性哪些方法以及方法代码
  • Class对象不同Class类加载生成java对象存放在堆空间,提供反射机制使用底层也是借用类元信息完成反射功能
1.2实例数据

对象属性的值数据

1.3填充字节

默认8字节对齐

保证对象大小8整数

2 通过jol计算对象大小

依赖

<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.10</version></dependency>

分析Object对象大小

  • 代码

public static void main(String[] args) {ClassLayout classLayout = ClassLayout.parseInstance(new Object());System.out.println("对象信息===================");System.out.println(classLayout.toPrintable());System.out.println("类信息===================");classLayout = ClassLayout.parseClass(Object.class);System.out.println(classLayout.toPrintable());
}

  • 输出

分析int[]对象大小

  • 代码

public static void main(String[] args) {ClassLayout classLayout = ClassLayout.parseInstance(new int[]{1,2,3});System.out.println("对象信息===================");System.out.println(classLayout.toPrintable());System.out.println("类信息===================");classLayout = ClassLayout.parseClass(int[].class);System.out.println(classLayout.toPrintable());
}

  • 输出

分析自定义类App对象大小

  • 代码

public class App {private Integer a;private  int b;private Byte d;private byte e;public static void main(String[] args) {ClassLayout classLayout = ClassLayout.parseInstance(new App());System.out.println("对象信息===================");System.out.println(classLayout.toPrintable());System.out.println("类信息===================");classLayout = ClassLayout.parseClass(App.class);System.out.println(classLayout.toPrintable());}
}

  • 输出

结论

  • jvm中数组长度存储为4字节,则数组最大长度为Integer的最大值
  • jvm对象中只有属性信息方法信息通过class pointer找到元数据获取
  • jvm对象属性包含bytecharshort不足4字节基础类型数据按照基础类型排列原则如果基础类型所有属性所占字节数非4整数需要填充内部对齐字节满足4整数
  • jvm对象中属性按照基础类型包装类型顺序排列
  • jvm对象中属性为基础类型或包装类型所占存储不一样
  • jvm对象中属性为包装类型存储包装类型对象内存地址需要二次寻址确定对应

思考:

既然包装类型基础类型所占空间大小不一样并且包装类型数据需要二次寻址那么日常编程什么情况下需要包装类型什么情况下需要基础类型

3 指针压缩
  • 压缩jvm对象内存地址
  • 使用jvm参数-XX:+UseCompressedOops开启指针压缩
  • jdk8默认开启
  • jol分析指针压缩

http://www.lryc.cn/news/516051.html

相关文章:

  • 联邦学习和大模型相结合: 数据隐私,提升训练效率,架构优化
  • 命令别名和命令历史
  • 打造三甲医院人工智能矩阵新引擎(二):医学影像大模型篇--“火眼金睛”TransUNet
  • Scade pragma: separate_io
  • IWOA-GRU和GRU时间序列预测(改进的鲸鱼算法优化门控循环单元)
  • “知识图谱AI教学辅助系统:点亮智慧学习的新灯塔
  • 产品 防尘防水IP等级 划分与实验方法
  • 【微服务】1、引入;注册中心;OpenFeign
  • 01、Docker学习,第一天:简单入门与安装
  • C++STL中iomanip的使用与细节
  • 3.C语言变量的基础概念与使用
  • Go语言中的逃逸分析:深入浅出
  • 【FlutterDart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100)
  • 【论文笔记】LongLoRA: Efficient Fine-tuning of Long-Context Large Language Models
  • 数据挖掘——朴素贝叶斯分类
  • unity中的UI系统---GUI
  • 鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
  • C语言冒泡排序教程简介
  • Fabric链码部署测试
  • k620老显卡,装cuda.等。
  • 网站常用功能模块-鉴权
  • 直接插入排序、折半插入排序、2路插入排序、希尔排序
  • FQ-GAN代码解析
  • 如何恢复已删除的 Telegram 消息 [iOSamp;Android]
  • asp.net core中的 Cookie 和 Session
  • Python实现一个简单的 HTTP echo 服务器
  • Ruby 中文编码
  • 淘金优化算法的信息共享与更新机制改进
  • Python中的ast.literal_eval:安全地解析字符串为Python对象
  • 【AI数学基础】线性代数:内积和范数