Java计算对象大小的方法详解

 更新时间:2025年01月10日 08:48:17   作者:千千寰宇  
在Java应用程序的性能优化场景中,时常需要考虑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

		Map<String, String> map = new HashMap<>();
        objectSizeBytes = ObjectSizeCalculator.getObjectSize(number);
        log.info("objectSizeBytes: {} bytes", objectSizeBytes );//48 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 字节。

到此这篇关于Java计算对象大小的方法详解的文章就介绍到这了,更多相关Java计算对象大小内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何解决Webservice第一次访问特别慢的问题

    如何解决Webservice第一次访问特别慢的问题

    这篇文章主要介绍了如何解决Webservice第一次访问特别慢的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • idea普通javaweb项目如何部署到tomcat(读取web.xml文件)

    idea普通javaweb项目如何部署到tomcat(读取web.xml文件)

    这篇文章主要介绍了idea普通javaweb项目如何部署到tomcat(读取web.xml文件),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Lombok注解之@SuperBuilder--解决无法builder父类属性问题

    Lombok注解之@SuperBuilder--解决无法builder父类属性问题

    这篇文章主要介绍了Lombok注解之@SuperBuilder--解决无法builder父类属性问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • Java底层基于二叉搜索树实现集合和映射/集合Set功能详解

    Java底层基于二叉搜索树实现集合和映射/集合Set功能详解

    这篇文章主要介绍了Java底层基于二叉搜索树实现集合和映射/集合Set功能,结合实例形式分析了Java使用二叉搜索树实现集合和映射相关操作技巧,需要的朋友可以参考下
    2020-03-03
  • Java spring的三种注入方式详解流程

    Java spring的三种注入方式详解流程

    Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版。Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率
    2021-10-10
  • Java棋类游戏实践之中国象棋

    Java棋类游戏实践之中国象棋

    这篇文章主要为大家详细介绍了Java棋类游戏中的中国象棋实现方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • Spring Cloud Config Client超时及重试示例详解

    Spring Cloud Config Client超时及重试示例详解

    这篇文章主要给大家介绍了关于Spring Cloud Config Client超时及重试的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2018-05-05
  • 详解JAVA后端实现统一扫码支付:微信篇

    详解JAVA后端实现统一扫码支付:微信篇

    本篇文章主要介绍了详解JAVA后端实现统一扫码支付:微信篇,这里整理了详细的代码,有需要的小伙伴可以参考下。
    2017-01-01
  • SpringBoot利用@Retryable注解实现接口重试

    SpringBoot利用@Retryable注解实现接口重试

    本文主要介绍了springboot如何利用@Retryable注解实现接口重试功能,文中示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Java访问权限原理与用法详解

    Java访问权限原理与用法详解

    这篇文章主要介绍了Java访问权限,结合实例形式详细分析了java构造者思想、包、访问修饰符等相关原理、应用与操作注意事项,需要的朋友可以参考下
    2020-02-02

最新评论