[Java] 计算Java对象大小

news/2025/1/9 20:55:52/文章来源:https://www.cnblogs.com/johnnyzen/p/18662883

  • 在Java应用程序的性能优化场景中,时常需要考虑Java对象的大小,以便评估后,进一步提出优化方案:
  • 占用内存的大小。(比如 本地内存)
  • 对象数据在网络传输中占用的网络带宽
  • 对象数据在存储时占用的磁盘空间
  • ...

概述

对象大小如何计算

  • 对象大小包括俩部分的内容,对象头和对象内容:

对象头

此处假设是64位的JVM

  • 对象地址,占4个字节。
  • 对象标记,占8个字节,包括锁标记,hashcode, age 等。
  • 数组长度标记,占4个字节。如果对象是一个数组,会有此标记,否则没有。

对象内容

  • 对象内部属性。如果属性是对象的话,那么记录的是对象的地址,占用4个字节。

8字节对齐

  • Java对象采用的是8字节对齐。对象大小必须是8的倍数,不足需要补齐。

比如,计算一个对象只需要20字节,那么实际占用24字节。

计算对象大小的方法

  • 方法1和方法2,在 String 对象的计算上,存在差异;Integer 和 Map 的计算,经简单检验:不存在差异。

方法1:基于 JDK 原生库 【推荐】

jdk 1.8

import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class ObjectCalculatorTest {public static void main(String[] args) {String text = "Hello World!"; //12 charsLong objectSizeBytes = ObjectSizeCalculator.getObjectSize(text);log.info("objectSizeBytes: {} bytes", objectSizeBytes );//64 bytesInteger number = new Integer(11);objectSizeBytes = ObjectSizeCalculator.getObjectSize(number);log.info("objectSizeBytes: {} bytes", objectSizeBytes );//16 bytes}
}

方法2:基于lucene-core

  • 引入依赖
<dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>8.7.0</version>
</dependency>
  • 计算对象大小

jdk 1.8

import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.util.RamUsageEstimator;@Slf4j
public class ObjectCalculatorTest {public static void main(String[] args) {String text = "Hello World!"; //12 char = 12 byteobjectSizeBytes = RamUsageEstimator.shallowSizeOf( text );log.info("objectSizeBytes: {} bytes", objectSizeBytes );//24 bytesInteger number = new Integer(11);System.out.println(RamUsageEstimator.shallowSizeOf(number));//16 bytesMap<String, String> map = new HashMap<>();System.out.println(RamUsageEstimator.shallowSizeOf(map));//48 bytes}
}

案例分析(基于lucene-core库)

Integer 对象大小分析

  • 它是对象,占用4个字节
  • 对象标记,占用8个字节
  • 查看源码,发现:

Integr 内容只有以下一个非static的属性,是一个int的基本类型属性,占用4个字节.
static 修饰的方法属性都是存储在方法区的,不占用对象空间。

    /*** The value of the {@code Integer}.** @serial*/private final int value;

故 total = 4 + 8 + 4 = 16

HashMap 对象大小分析

  • 它是对象,占用4个字节
  • 对象标记,占用8个字节
  • 查看源码,发现:

HashMap 是继承了 AbstractMap 的,AbstractMap 中有以下的俩个属性,一共占用8个字节。因为只是存储了keySet, values 的地址

transient Set<K>        keySet;
transient Collection<V> values;
  • HashMap 中有以下属性,共占用 6 * 4 = 24 个字节。
transient Node<K,V>[] table;
transient Set<Map.Entry<K,V>> entrySet;
transient int size;
transient int modCount;
int threshold;
final float loadFactor;

total = 4 + 8 + 8 + 24 = 44, 由于 java 是8字节对齐的,故一共是 48 字节。

X 参考文献

  • 计算Java对象大小(附实际例子分析) - CSDN

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

并行前缀(Parallel Prefix)加法器

并行前缀(Parallel Prefix)加法器 并行前缀加法器的基本介绍 二进制加法器是目前数字计算单元中的重要模块,基础的加法器架构包括行波进位加法器(Ripple Carry Adder),超前进位加法器(Carry Look-Ahead Adder),进位选择加法器(Carry Select Adder)等。加法器的进位传…

科技风?写实风?教你设置多风格三维地图

概述 三维地图通过高度、深度、立体感等表现形式,能够真实还原地形地貌、城市建筑和空间结构。相比二维地图,它能够更清晰地展示复杂的地理数据,帮助用户快速理解空间关系,如地形起伏、建筑高度等。在实际应用中,我们可以将不同风格的三维地图作为项目的主体元素进行展示,…

【模拟电子技术】03-PN与二极管的特性

【模拟电子技术】03-PN与二极管的特性上节中有提到对PN结施加反向电压时,会使得PN结所形成的势垒增加,阻止多子到另一边。在掺杂浓度比较低的时候,外加电场加强,中间的耗尽层会加长,变成了一个粒子加速器,自由电子进去后不断加速。直到某一电场强度时,粒子加速足够大的时…

NocoBase 本周更新汇总:支持大规模数据量的导入和导出

本周更新包括:支持大规模数据量的导入和导出等。汇总一周产品更新日志,最新发布可以前往我们的博客查看。 NocoBase 目前更新包括的版本更新包括三个分支:main ,next和 develop。main :截止目前最稳定的版本,推荐安装此版本。 next:包含即将发布的新功能,经过初步测试的…

MSSQL:DBLINK连接oracle 19

无法为该请求检索数据。(Microsoft.SqlServer.Management.Sdk.Sfc)其他信息:执行Transact-SQL语句或批处理时发生了异常。(Microsoft.SqlServer.ConnectionInfo)在与SQL Server 建立连接时出现与网络相关的特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正…

五款强大报表软件助力企业提升数据分析效率

本文将为大家介绍五款功能强大的报表软件,包括山海鲸报表、JReport、Power BI、Zoho Analytics 和 SAP Crystal Reports。这些工具各具特色,能够帮助企业快速生成数据报表并进行深度分析。无论是数据可视化、报表定制、自动化生成还是与其他系统的集成,它们都能为企业的决策…

Linq中的设置操作 (C#):Distinct 和 DistinctBy、Except 和 ExceptBy、Intersect 和 IntersectBy、Union 和 UnionBy

LINQ 中的集运算是指根据相同或单独集合中是否存在等效元素来生成结果集的查询运算。 注:这些示例使用 System.Collections.Generic.IEnumerable<T> 数据源。 基于 System.Linq.IQueryProvider 的数据源使用 System.Linq.IQueryable<T> 数据源和表达式树。 表达式…

2025多校冲刺省选模拟赛3

过于困难,直接放弃2025多校冲刺省选模拟赛3\(T1\) A. 等差 \(100pts/100pts\)考虑哈希,每 \(k\) 个作为一组与上一组统一计算。取 \(Base>\) 值域时用高精度来存储并判断的正确性显然。观察到可行的最小的 \(k\) 单调不降,不妨直接枚举答案。暴力实现时间复杂度为 \(O(n…

还不会 Cert Manager 自动签发证书?一文掌握

相信很多小伙伴对于 Cert Manager 不陌生,Cert Manager 是 Kubernetes 上的证书管理工具,基于 ACME 协议与 Lets Encrypt 签发免费证书并为证书自动续期,实现永久免费使用证书。 本文将介绍如何使用 Cert Manager 实现自动签发证书并与 Rainbond 结合使用。 Cert Manager 概…

JAVA-Day 09:While循环语句

While循环 while循环格式 初始化语句; while(条件判断语句){ 循环体语句; 条件控制语句; } 初始化语句只执行一次 判断语句为True,循环继续 判断语句为False,循环结束 例: 世界最高山峰珠穆朗玛峰的高度为8844.43米=8844430毫米,假如有 一张足够大的纸,它的厚度为0.1毫米。…

rust学习十六.2、并发-利用消息传递进行线程间通讯

通过信道是rust的解决线程之间通信的2个工具之一,另外1个是是共享内存状态。 rust推出这个,明显地是因为受到go之类的影响。 在书籍中,作者提到go编程文档中的内容: 不要通过共享内存来通讯;而是通过通讯来共享内存(Do not communicate by sharing memory; instead, share…

2025,谁会成为 AI Agent 的新入口?|播客《编码人声》

「编码人声」是由「RTE开发者社区」策划的一档播客节目,关注行业发展变革、开发者职涯发展、技术突破以及创业创新,由开发者来分享开发者眼中的工作与生活。2024 年末,一群来自 Android、Chrome OS、Oculus 等操作系统的开发元老联合创业,推出 AI Agent 操作系统 /dev/agen…