• 在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对象大小的更多相关文章

  1. Coherence对象压缩以及对象大小计算

    1.通过util.zip带的gzip压缩程序  Coherence对象压缩程序如下 package coherencetest; import com.tangosol.net.CacheFactor ...

  2. Java对象大小计算

    这篇说说如何计算Java对象大小的方法.之前在聊聊高并发(四)Java对象的表示模型和运行时内存表示 这篇中已经说了Java对象的内存表示模型是Oop-Klass模型. 普通对象的结构如下,按64位机 ...

  3. 计算Java对象内存大小

    摘要 本文以如何计算Java对象占用内存大小为切入点,在讨论计算Java对象占用堆内存大小的方法的基础上,详细讨论了Java对象头格式并结合JDK源码对对象头中的协议字段做了介绍,涉及内存模型.锁原理 ...

  4. 准确计算Java中对象的大小

    由于在项目中需要大致计算一下对象的内存占用率(Hadoop中的Reduce端内存占用居高不下却又无法解释),因此深入学习了一下如何准确计算对象的大小. 使用system.gc()和java.lang. ...

  5. 如何准确计算Java对象的大小

    如何准确计算Java对象的大小 原创文章,转载请注明:博客园aprogramer 原文链接:如何准确计算Java对象的大小      有时,我们需要知道Java对象到底占用多少内存,有人通过连续调用两 ...

  6. 两种计算Java对象大小的方法

    之前想研究一下unsafe类,碰巧在网上看到了这篇文章,觉得写得很好,就转载过来.原文出处是: http://blog.csdn.net/iter_zc/article/details/4182271 ...

  7. java调优随记-java对象大小

    在java中,基本数据类型的大小是固定.但是java对象的大小是不固定的,需要通过计算. 在java中,一个空对象(没有属性和方法的对象)在堆中占用8byte,比如 Object obj = new ...

  8. Java虚拟机14:Java对象大小、对象内存布局及锁状态变化

    一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...

  9. Java对象大小:size和retained size

    最近看到网上很多文章讲如何计算java对象的大小(size),很多观点不敢苟同. 这是其中一篇比较靠前的文章,写的也比较全面: http://blog.csdn.net/iter_zc/article ...

  10. Java虚拟机18:Java对象大小、对象内存布局及锁状态变化

    一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法.不过还好,在JDK1.5之后引入了Instrumentation类,这个 ...

随机推荐

  1. 开源 PHP 商城项目 CRMEB 安装和使用教程

    说到电商系统,很多人第一反应可能是 Shopify 或 Magento.没错,这些平台确实功能强大,但是...它们也太强大了,不仅复杂还昂贵,对于刚起步的创业者来说简直是压力山大. 但是从零开始开发一 ...

  2. 国内985大学计算机方向硕博高性价比灌水的SCI期刊pr、kbs、eswa、ieee tii、ieee tiv具体都是啥?

    国内985大学计算机方向硕博高性价比灌水的SCI期刊pr.kbs.eswa.ieee tii.ieee tiv,下面给出具体名称: Pattern Recognition(PR) Knowledge- ...

  3. 基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现六

    一.前言介绍: 1.1 项目摘要 随着电子商务的迅猛发展和城市化进程的加快,快递业务量呈现出爆炸式增长的趋势.传统的快递寄取方式,如人工配送和定点领取,已经无法满足现代社会的快速.便捷需求.这些问题不 ...

  4. SqlLite查看工具

    有时候想查看下sqllite,又不需要功能齐全的客户端,SQLiteSpy是个临时应急的好工具(也许本身功能就很强,没仔细研究). https://files.cnblogs.com/files/ja ...

  5. rabbitmq消息中间件的初步探索

    在上次学xattr的时候用它简单实现一个中间件,我去了解了一下rabbitmq这个消息中间件,感觉理论上还是挺好用的,给一般并发量的系统用足够了. 首先安装这个服务. sudo apt search ...

  6. mkdir递归创建文件夹

    mkdir -p  能递归创建文件夹 mkdir 只能创建一级文件夹,如果父文件夹不存在 则报错,所以如果你想用一个很确定的路径 在SHELL脚本里面可以直接写 mkdir -p /home/log/ ...

  7. Open-RAG:将开源LLM模型集成为高效RAG模型 | ENMLP'24

    本文是对公开论文的核心提炼,旨在进行学术交流.如有任何侵权问题,请及时联系号主以便删除. 来源:晓飞的算法工程笔记 公众号,转载请注明出处 论文: Open-RAG: Enhanced Retriev ...

  8. ArrayList源码分析(基于JDK1.6)

    不积跬步,无以至千里:不积小流,无以成江海.从基础做起,一点点积累,加油! <Java集合类>中讲述了ArrayList的基础使用,本文将深入剖析ArrayList的内部结构及实现原理,以 ...

  9. golang之json.RawMessage

    RawMessage 具体来讲是 json 库中定义的一个类型.它实现了 Marshaler 接口以及 Unmarshaler 接口,以此来支持序列化的能力.注意上面我们引用 官方 doc 的说明. ...

  10. 接口文档解决方案之Torna

    ◆一.开源项目简介 接口文档解决方案,目标是让接口文档管理变得更加方便.快捷.Torna采用团队协作的方式管理和维护接口文档,将不同形式的文档纳入进来统一维护. Torna弥补了传统文档生成工具(如s ...