首页 > 极客资料 博客日记
[Java] 计算Java对象大小
2025-01-09 21:00:03极客资料围观2次
本篇文章分享[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 参考文献
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签: