当前位置: 首页 > 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.xdnf.cn/news/1377829.html

相关文章:

  • Linux--->网络编程(TCP并发服务器构建:[ 多进程、多线程、select ])
  • Linux 系统调优与CPU-IO-网络内核参数调优
  • MySQL InnoDB vs MyISAM
  • 深度学习——卷积神经网络CNN(原理:基本结构流程、卷积层、池化层、全连接层等)
  • LeetCode - 反转链表 / K 个一组翻转链表
  • day2_softmax回归的实现 李沐动手学深度学习pytorch记录
  • 神经网络学习笔记12——高效卷积神经网络架构MobileNet
  • PLC_博图系列☞基本指令”S_ODT:分配接通延时定时器参数并启动“
  • leecode-三数之和
  • 如何防御安全标识符 (SID) 历史记录注入
  • 【Linux实时内核机制】ww_rt_mutex 的contending_lock异常问题
  • wireshark解析FLV插件分享
  • Unity Shader unity文档学习笔记(二十一):几种草体的实现方式(透明度剔除,GPU Instaning, 曲面细分+几何着色器实现)
  • HTML5超详细学习内容
  • GPIO推挽和开漏的名称由来和本质含义
  • FactoryBean接口作用
  • 使用Stone 3D快速制作第一人称视角在线小游戏
  • 【PyTorch】基于YOLO的多目标检测项目(二)
  • 基于Cursor AI IDE的Vue3留言板系统实战:从零搭建到智能优化全流程
  • 《金融对账系统雪崩隐患的深度复盘与架构重生》
  • 从CTFshow-pwn入门-pwn40理解64位栈溢出不都需要堆栈平衡
  • 致远OA新闻公告讨论调查信息查询SQL
  • Linux操作系统——TCP服务端并发模型
  • 域名、ip、DSN、URL
  • 虚拟机逃逸攻防演练
  • 装饰器模式(C++python)
  • 如何提升素材检索效率?语义搜索在 DAM 中的应用效果全解
  • 广东省省考备考(第八十八天8.27)——判断推理(听课后强化训练)
  • 基于NXP iMXRT600音频算法开发方法
  • 【ros-humble】【虚拟机】网络配置