new Object到底占用多少内存?

前言

通过 JOL 工具,深入剖析对象头、实例数据以及内存对齐的具体细节,了解 JVM 是如何管理和优化内存的。使用 JOL,验证内存结构,直观地观察 JVM 参数(如对象指针压缩、类指针压缩等)对对象布局的影响。

一、工具介绍

JOL(Java Object Layout) 是一个由 OpenJDK提供的工具库,用于分析和展示 Java 对象的内存布局、对象头、对象大小以及各种内存偏移量等信息。它对于研究 Java 内存管理、理解对象布局和 JVM 内部机制非常有帮助。

JOL 的核心功能

  1. 对象布局分析
    JOL 可以展示 Java 对象在内存中的布局细节,比如对象头、字段偏移量、实例大小等。它会根据不同的 JVM 配置(如是否启用压缩指针)给出对象的实际内存布局。
  2. 对象头分析
    JOL能展示对象头的详细信息,包括Mark Word、类指针和数组长度等。对象头是 JVM 用来管理对象状态的重要部分,它包含锁信息、GC 状态和哈希码等内容。
  3. 压缩指针(Compressed Oops)支持
    JOL 支持在开启和关闭指针压缩(Compressed Oops)的情况下,展示对象的内存布局差异。通过对比,可以看到指针压缩对对象大小的影响。
  4. 对象对齐与填充
    JOL 能显示对象的内存对齐和填充情况。由于 JVM 的内存布局需要满足对齐要求(通常是 8 字节),所以某些对象可能会被填充以满足内存对齐规则。
  5. 数组布局
    JOL 支持对数组对象的布局分析,可以查看数组对象头和每个数组元素在内存中的布局。

二、JOL使用

2.1添加JOL依赖

在Maven项目中使用以下方式添加 JOL 依赖:

<!-- 对象内存分布工具 -->
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.17</version>
</dependency>

2.2使用JOL进行对象内存分析

一个简单的测试类

package com.lazy.snail.jvm;import org.openjdk.jol.info.ClassLayout;/*** @ClassName ObjectTest* @Description TODO* @Author lazysnail* @Date 2024/11/12 16:12* @Version 1.0*/
public class ObjectTest {public static void main(String[] args) {Object obj = new Object();String layout = ClassLayout.parseInstance(obj).toPrintable();System.out.println(layout);}
}

三、对象内存布局详解

以2.2输出结果作为分析样例:

输出结果:

java.lang.Object object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)8   4        (object header: class)    0xf80001e512   4        (object alignment gap)    
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

3.1表头

  1. OFF:内存布局中的偏移量

  2. SZ:内存中占用的字节数

  3. TYPE:数据类型(普通字段:显示具体的数据类型;对象头信息:通常为空)

  4. DESCRIPTION:(普通字段:字段名称;对象头信息:mark表示标记字段、class表示类指针、gap表示内存填充)

  5. VALUE:

    • 对于对象头中的mark word,VALUE表示对象的标记状态,如锁状态、哈希码等。

    • 对于类指针,VALUE显示的是类元数据的地址。

    • 对于普通字段,VALUE显示字段的当前值。

3.2标记字(Mark Word)

在 64 位 JVM 中,mark word占 8 字节(64 位),在2.2的输出结果中,可以看档第一行数据便是对象头中的标记字,占用了8个字节。

mark word是对象头中一个高度复用的区域,它的内容会根据对象的状态变化而调整。它不仅仅是锁信息的存储地,还包含了对象的哈希值、GC 标记、分代年龄等重要信息。在 JVM 的内部实现中,mark word帮助实现了 Java 对象的高效锁管理和垃圾回收优化。

下表是不同状态下对象头中存储的信息:

1b553c9ec427920e8eb945be18ab3ed3

3.3类指针

类指针也是对象头的一部分,从2.2的输出结果中可以看出,类指针占用了4字节。

3.3.1类指针位置及作用:
  • 类指针指向的是该对象的类元数据。
  • 类指针是对象头中的一部分,它使 JVM 能够通过这个指针找到对象的类信息:
    1. 字段布局:了解对象有哪些字段以及每个字段的位置和类型。
    2. 方法表:包含了这个类定义的所有方法,用于方法调用。
    3. 继承信息:包含该类的父类、接口等信息,用于类型检查和多态支持。
3.3.2类指针压缩

在 64 位 JVM 中,为了节省内存,JVM 会启用类指针压缩(Compressed Class Pointers)。当类指针压缩开启时(通过 -XX:+UseCompressedClassPointers,通常在默认情况下开启),JVM 会将类指针压缩到 32 位以节省内存空间。这在对象数量较多的应用中可以显著减少内存消耗。

查看是否开启了类指针压缩:

#JVM运行时参数查看
java -XX:+PrintCommandLineFlags -version

结果:

-XX:ConcGCThreads=2 -XX:G1ConcRefinementThreads=8 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=268435456 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4294967296 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC
java version "17.0.11" 2024-04-16 LTS
Java(TM) SE Runtime Environment (build 17.0.11+7-LTS-207)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.11+7-LTS-207, mixed mode, sharing)

从结果中可以看到-XX:+UseCompressedClassPointers,确实是默认开启的。

禁用类指针压缩:

现在我们在运行2.2测试类时将类指针压缩关闭:

image-20241112234346607

运行结果:

java.lang.Object object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)8   8        (object header: class)    0x0000000125001d30
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

可以从结果看出,当我们把类指针关闭压缩禁用之后,对象头中的类指针变成了8个字节。

3.4对齐

从2.2的运行结果中看到,"object alignment gap"存在四字节的补位对齐的情况。

这是由于HotSpot JVM 采用 8 字节对齐,本身obj实例的大小是12字节,不是8的倍数,需要补上4个字节的内存,使其占用空间变成8的倍数。

至于为什么默认采用8字节对齐,涉及到内存访问效率、CPU缓存行对齐、内存碎片化等等。

对齐策略能修改吗?能,但是真没干过,看一看效果:

运行测试类时,加上-XX:ObjectAlignmentInBytes=32,将补齐策略修改成32位补齐

image-20241113000542836

输出结果:

java.lang.Object object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)8   4        (object header: class)    0x00040fc012  20        (object alignment gap)    
Instance size: 32 bytes
Space losses: 0 bytes internal + 20 bytes external = 20 bytes total

可以看出,为了满足32位的补齐策略,无端的耗费了20字节的内存。

四、总结

当执行Object obj = new Object();时,对象的内存布局主要包括以下几部分:

对象头

  • Mark Word:用于存储对象的标记信息,包括对象的哈希码、GC 状态、锁状态等。大小通常为 8 字节。
  • Class Pointer:指向对象所属类(Object 类)的指针,帮助 JVM 知道该对象的类信息。通常占 4 或 8 字节,取决于是否启用了类指针压缩。

实例数据Object 类没有实例字段,因此这一部分为空,但仍需要空间来满足对象对齐要求。

对齐填充:为了满足 8 字节对齐要求,JVM 会在对象末尾增加填充字节(如果需要)。

[!NOTE]

对象引用本身也占用空间,大小为 4 字节或 8 字节,具体取决于是否启用了 对象引用指针压缩

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/13609.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解接口测试:实用指南与最佳实践5.0(二)

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

基于Java+SpringBoot宠物管理系统

一、作品包含 源码数据库设计文档全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据库&…

PYNQ 框架 - 中断(INTR)驱动

目录 1. 简介 2. 分析 2.1 Block Design 2.2 AXI Timer 2.2.1 IP 基本信息 2.2.2 IP 地址空间 2.2.3 级联模式 2.2.4 生成/捕获模式 2.3 AXI Interrupt 2.3.1 IP 基本信息 2.3.2 IP 地址空间 2.3.3 相关概念 2.3.4 参数配置 2.3.5 中断确认寄存器 3. PYNQ 代码 …

使用runtime/pprof包进行Go程序性能调优的实战教程

使用runtime/pprof包进行Go程序性能调优的实战教程 引言基本概念什么是runtime/pprof使用场景 安装和设置环境要求导入runtime/pprof包 基本用法创建和启动一个新的profile停止和销毁一个profile CPU Profiling启动CPU profiling停止CPU profiling分析CPU profiling数据 内存Pr…

深度探秘 VGG 网络:从原理到应用的视觉传奇

VGG 网络的原理 一、整体架构 VGG&#xff08;Visual Geometry Group&#xff09;网络是一种深度卷积神经网络&#xff0c;其显著特点是简洁而高效的架构设计。VGG 网络主要由卷积层、池化层和全连接层组成。 卷积层&#xff1a; 如前所述&#xff0c;VGG 大量使用 的小卷积…

为什么我搞量化分析要特别关注行业产业链

因为看了这本书理论书。我都是用现成的理论来传串起来的。每一步都是背后都有现成的理论支持支撑。虽然看着简单&#xff0c;我这个工具策略参考了投资行为心理学。主要是为了我量身定做的。我也是刚刚研究的新手&#xff0c;碰到的很多问题很多人应该也碰到&#xff0c;就把这…

电商数据接口||淘宝|京东商品详情参数对比

淘宝/天猫获得淘宝商品详情 API 返回值说明 item_get-获得淘宝商品详情 taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中…

Spring Security 认证流程,长话简说

一、代码先行 1、设计模式 SpringSecurity 采用的是 责任链 的设计模式&#xff0c;是一堆过滤器链的组合&#xff0c;它有一条很长的过滤器链。 不过我们不需要去仔细了解每一个过滤器的含义和用法,只需要搞定以下几个问题即可&#xff1a;怎么登录、怎么校验账户、认证失败…

HTMLCSS 打造的酷炫菜单选项卡

效果演示 具有视觉吸引力的菜单选项 HTML <div class"card"><ul><li class"iso-pro"><span></span><span></span><span></span><a href""><svgviewBox"0 0 320 512&quo…

【linux】网络基础 ---- 传输层

1. UDP协议 &#xff08;一&#xff09;UDP协议端格式 注意&#xff1a; 16位UDP长度, 表示整个数据报(UDP首部UDP数据)的最大长度16位UDP检验和&#xff0c;能判断是否出现数据丢失等问题如果校验和出错, 就会直接丢弃 UDP报头本质上也是一个结构体&#xff1a; 操作系统内有…

软件包管理

软件安装 软件包管理器 APT&#xff08;Advanced Package Tool&#xff09;&#xff1a; 发行版&#xff1a;主要用于 Debian 及其衍生版&#xff08;如 Ubuntu&#xff09;。 常用命令&#xff1a; apt-get install &#xff1a;安装软件包。 apt-get update&#xff1a;更新…

[项目代码] YOLOv5 铁路工人安全帽安全背心识别 [目标检测]

YOLOv5是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv5具有更高的…

Linux逻辑卷

文章目录 逻辑卷 &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Linux专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月12日11点09分 逻辑卷 LVM逻辑卷管理是Linux环境中对磁盘分区进行管理的一种机制&#xff0c;建立在硬盘和分区之…

【设计模式】创建型设计模式-工厂模式的实现

工厂模式实现 定义例子UML类图理解Java代码实现总结 定义 工厂方法模式定义了一个接口用于创建对象&#xff0c;该模式由子类决定实例化哪个工厂类。该模式把类的实例化推迟到了子类。 例子 通过一个公共的类方法来管理画图对象的创建。 UML类图理解 Java代码实现 定义接口…

Spring Boot实战:编程训练系统开发手册

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理编程训练系统的相关信息成为必然。开发合适…

方案丨车险保单OCR:3秒钟完成保单审核

在涉及车辆交易的各种情况下&#xff0c;记录和管理车险保单信息是一项必不可少的任务。然而&#xff0c;面对数量庞大的电子保单&#xff0c;传统的手工录入方式显得尤为低效——它不仅消耗大量时间&#xff0c;而且容易出现错误&#xff0c;这不仅影响了用户的满意度&#xf…

性能测试|JMeter接口与性能测试项目

前言 在软件开发和运维过程中&#xff0c;接口性能测试是一项至关重要的工作。JMeter作为一款开源的Java应用&#xff0c;被广泛用于进行各种性能测试&#xff0c;包括接口性能测试。本文将详细介绍如何使用JMeter进行接口性能测试的过程和步骤。 JMeter是Apache组织开发的基…

嵌入式硬件电子电路设计(五)MOS管详解(NMOS、PMOS、三极管跟mos管的区别)

引言&#xff1a;在我们的日常使用中&#xff0c;MOS就是个纯粹的电子开关&#xff0c;虽然MOS管也有放大作用&#xff0c;但是几乎用不到&#xff0c;只用它的开关作用&#xff0c;一般的电机驱动&#xff0c;开关电源&#xff0c;逆变器等大功率设备&#xff0c;全部使用MOS管…

如何优化开放数据湖仓一体的性能

数据湖仓一体架构由 Apache Hudi、Apache Iceberg 和 Delta Lake 等开放表格式提供支持&#xff0c;提供了一种开放且经济高效的方式来管理组织不断增长的数据和分析需求。它提供了在同一数据存储上运行并发事务的可靠性&#xff0c;从而提高了效率。数据湖仓一体支持关键功能&…

比较基因组分析

比较基因组分析&#xff08;Comparative Genomics Analysis&#xff09;是一门通过比较不同物种或个体的基因组序列来研究其相似性与差异性的科学方法。它有助于揭示物种间的进化关系、基因功能、生物适应性及潜在的疾病机制。近年来&#xff0c;随着高通量测序技术的发展&…