[Java] 计算Java对象大小
序
- 在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 chars
Long objectSizeBytes = ObjectSizeCalculator.getObjectSize(text);
log.info("objectSizeBytes: {} bytes", objectSizeBytes );//64 bytes
Integer 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 byte
objectSizeBytes = RamUsageEstimator.shallowSizeOf( text );
log.info("objectSizeBytes: {} bytes", objectSizeBytes );//24 bytes
Integer number = new Integer(11);
System.out.println(RamUsageEstimator.shallowSizeOf(number));//16 bytes
Map<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] 计算Java对象大小的更多相关文章
- Coherence对象压缩以及对象大小计算
1.通过util.zip带的gzip压缩程序 Coherence对象压缩程序如下 package coherencetest; import com.tangosol.net.CacheFactor ...
- Java对象大小计算
这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机 ...
- 计算Java对象内存大小
摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...
- 准确计算Java中对象的大小
由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...
- 如何准确计算Java对象的大小
如何准确计算Java对象的大小 原创文章,转载请注明:博客园aprogramer 原文链接:如何准确计算Java对象的大小 有时,我们需要知道Java对象到底占用多少内存,有人通过连续调用两 ...
- 两种计算Java对象大小的方法
之前想研究一下unsafe类,碰巧在网上看到了这篇文章,觉得写得很好,就转载过来.原文出处是: http://blog.csdn.net/iter_zc/article/details/4182271 ...
- java调优随记-java对象大小
在java中,基本数据类型的大小是固定.但是java对象的大小是不固定的,需要通过计算. 在java中,一个空对象(没有属性和方法的对象)在堆中占用8byte,比如 Object obj = new ...
- Java虚拟机14:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
- Java对象大小:size和retained size
最近看到网上很多文章讲如何计算java对象的大小(size),很多观点不敢苟同. 这是其中一篇比较靠前的文章,写的也比较全面: http://blog.csdn.net/iter_zc/article ...
- Java虚拟机18:Java对象大小、对象内存布局及锁状态变化
一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...
随机推荐
- 我用Replicate训练了个纹身Flux AI LORA模型,分享下经验
# 我用Replicate训练了个纹身AI模型,分享下经验 ## 起因 最近一直在研究AI辅助设计,正好我对纹身设计特别感兴趣.经过一段时间摸索,用Replicate平台训练了一个还不错的纹身设计模型 ...
- python翻译词典实例
#!/usr/bin/python # -*- coding:utf-8 -*- #通过有道翻译来进行内容翻译 import urllib2 import urllib import json #-- ...
- 在Keil中使用ST-LINK烧录STM32程序指南
前言 之前玩STM32都是用J-LINK烧录程序,不仅便捷,而且烧录的速度比用串口快好多. 最近我接了几个32单片机的毕设单子,便买了几块C8T6的最小系统板用来开发.最初我还是用J-LINK烧录C8 ...
- 2023NOIP A层联测16 T3 货物运输
2023NOIP A层联测16 T3 货物运输 题目描述说这是一个仙人掌图,通常将问题转换为环和树的问题在使用圆方树来解决. 树解法 令 \(a_i=s_i-\frac{\sum s_i}{n}\) ...
- 不错的PHP扩展
不错的PHP扩展 ext name ext description ds data structure 提供list hash queue等数据结构 igbinary 数据压缩(速度快 压缩后内容小) ...
- 使用 ibatis 处理复杂对象数据关系的实例
如何使用 ibatis 处理复杂对象数据关系 iBatis 是一个开源的对象关系映射程序,其工作是将对象映射到 SQL 语句.和其它 O/R Mapping 框架不同,iBatis 开发者需要自己编写 ...
- vant中dialog的使用
按照文档上的方式引入组件,但是还是会报错说没有注册 引入方式如下: import { Cell, CellGroup, Field, Dialog } from 'vant'; components: ...
- 移动端NES网页模拟器(1)
前言 移动端浏览器是没有实体键盘的,想要操作游戏就必须为其设置虚拟按键,通过虚拟按键(按钮)的标识与实体键盘的keyCode进行绑定,来达到想要的效果. 这个随笔只封装NES游戏手柄右边的按键,不包含 ...
- 在CodeBolcks+wxWidgets下的C++编程教程——用向导创建一个wxWidgets项目(xTetris)
0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程.我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识. 了解我编写教 ...
- python+playwright安装+使用vsocde运行代码
python虚拟环境 1.安装python,环境配置 2.修改pip镜像源 3.新增虚拟环境 注意路径,例子的路径是在python的目录下生成一个venv文件夹 进入venv文件夹,使用virtual ...