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

JVM之【Java对象在内存中的结构】

目录

前言

对象的组成部分

对象头

实例数据

对齐填充

查看对象的组成结构和大小

添加依赖

查看Object对象占用的内存大小

查看数组对象占用的内存大小

查看上面example1占用内存大小

查看上面example2占用内存大小

相关的JVM参数


前言

Java程序运行过程中,大多数的对象会被分配到堆空间中存储,本文主要介绍Java对象在内存中的组成结构

对象的组成部分

Java对象一般由三个部分组成:对象头、实例数据和对齐填充

对象头

由如下几个部分组成

  • MarkWord,在64位虚拟机中占用8个字节
  • 类型指针,在64位虚拟机中且开启了指针压缩时占用4个字节
  • 数组长度(如果是数组对象),在64位虚拟机中占用4个字节

实例数据

下图中Example1类中有3个属性,两个int型一个long类型,此时对象example1的实例数据大小为:4+4+8=16字节

public class Example1 {// 4byteprivate int i1;// 4byteprivate int i2;// 8byteprivate long l1;public static void main(String[] args) {Example1 example1 = new Example1();}
}

下图中Example2类中有4个属性,2个int类型,1个long类型,1个引用类型(引用类型是直接存储指针的),在开启指针压缩时,example2的实例数据大小为:4+4+8+4=20字节

public class Example2 {// 4byteprivate int a;// 4byteprivate int b;// 8byteprivate long c;// 开启指针压缩占时占用4byteprivate Example1 e;public static void main(String[] args) {Example2 example2 = new Example2();}
}

对齐填充

在Java对象中,对齐填充可能存在也可能不存在,64位虚拟机规定Java对象的总大小必须是8的整数倍,所以当一个对象的头像头+实例数据大小不为8的整数倍时,会通过对齐填充的方式将对象的大小补齐成8的整数倍

查看对象的组成结构和大小

添加依赖

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

查看Object对象占用的内存大小

代码示例

import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Object object = new Object();System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}

运行结果:大小为16字节(8字节的MarkWord + 4字节的类型指针 + 4字节的对齐填充)

查看数组对象占用的内存大小

代码示例

import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Object object = new int[9];System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}

运行结果:56字节(8字节MarkWord + 4字节类型指针 + 4字节数组长度 + 4*9字节数组空间 + 4字节对齐填充)

查看上面example1占用内存大小

代码实例

import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Example1 object = new Example1();System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}

运行结果:32字节(有4字节的对齐填充)

查看上面example2占用内存大小

代码示例

import org.openjdk.jol.info.ClassLayout;public class WatchObj {public static void main(String[] args) {Object object = new Example2();System.out.println(ClassLayout.parseInstance(object).toPrintable());}
}

运行结果:32字节(没有对齐填充)

相关的JVM参数

  1. [-XX:+UseCompressedOops]:开启指针压缩
http://www.dtcms.com/a/353042.html

相关文章:

  • windows下 docker desktop 清理ext4.vhdx文件 并缩小ext4.vhdx文件
  • 二次校验请求源 IP 是否在 WAF 官方 IP 段内” + “校验是否携带 WAF 专属 HTTP 头
  • 基于Spark的白酒行业数据分析与可视化系统的设计与实现
  • [后端快速搭建]基于 Django+DeepSeek API 快速搭建智能问答后端
  • 域名、ip、DSN、URL
  • springbootr如何调用dolphinshceduler
  • 【记录】R|Windows 下的 R studio 安装调研准备工作、安装过程以及 ggplot2 包的引入测试
  • GIP电路
  • leetcode 974 和可被K整除的子数组
  • 【LeetCode 热题 100】287. 寻找重复数——双指针
  • 初始Linux——指令与权限
  • 【大前端】封装一个React Native与Android/IOS 端通用的埋点接口
  • 数据结构(C语言篇):(三)顺序表算法题解析
  • FPGA学习笔记——Verilog中可综合和常见的不可综合的系统函数
  • 数据结构:从堆中删除元素 (Deleting from a Heap)
  • 使用Spring Boot和EasyExcel导出Excel文件,并在前端使用Axios进行请求
  • linux-优化命令
  • Linux笔记11——shell编程基础-5
  • 使用appium对安卓(使用夜神模拟器)运行自动化测试
  • 解释器模式及优化
  • HIVE的Window functions窗口函数【二】
  • flume监控文件写入 Kafka 实战:解耦应用与消息队列的最佳实践
  • 性能测试-jmeter实战6
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(21):文法+单词第7回3
  • 学习嵌入式的第二十八天——线程
  • 趣味学Rust基础篇(变量与可变性)
  • RCLAMP0504M.TBT电子元器件Semtech 低电容、四通道TVS二极管阵
  • Web漏洞
  • More Effective C++条款12:理解抛出一个异常与传递一个参数或调用一个虚函数间的差异
  • 火焰传感器讲解