java对象内存到底占用多少

一个Java对象到底占用多大内存

Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)

对象占用的内存大小还受到VM参数是否开启指针压缩UseCompressedOops的影响

内存大小:(对象头 + 实例数据 + 对齐补充padding) % 8等于0 且 0 <= padding < 8

我所在的环境是64位HotSpot虚拟机,操作系统 64位Windows 7.以下例子均已不开启指针压缩,开启指针压缩计算方法类似,不再赘述

具体数据类型所占内存

一 对象头

对象头在32位系统上占用8bytes,64位系统上占用16bytes。

开启(-XX:+UseCompressedOops)对象头大小为12bytes(64位机器)。

MemoryCalculation.class类文件

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
	public static void main(String[] args) {
		System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new MemoryCalculation ())))	
	}
}

注: 所需SizeOf.jar包下载

编译执行:
javac MemoryCalculation.java -cp SizeOf.jar MemoryCalculation.java
java -javaagent:sizeOf.jar -XX:-UseCompressedOops MemoryCalculation

输出结果16.0b(对象头16 + 实例数据0 + 对齐补充0)

二 实例数据

原生类型(primitive type)的内存占用如下:

Primitive TypeMemory Required(bytes)
boolean1
byte1
short2
char2
int4
float4
long8
double8

reference类型在32位系统上每个占用4bytes, 在64位系统上每个占用8bytes。

三 数组对象

数组对象的对象头占用24个字节,启用压缩之后占用16个字节。

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
	public static void main(String[] args) {
		System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new Integer[0])))	
	}
}

输出结果24.0b(对象头24 + 实例数据长度 * 数据长度 + 对齐补充0)

复合对象

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
	static class B {
			int a;
			int b;
		}
	static class C {
			int ba;
			B[] as = new B[3];
			C() {
				for (int i = 0; i < as.length; i++) {
					as[i] = new B();
				}
			}
		}
	public static void main(String[] args) {
		System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new C())));				
	}
}

内存图:

未开启压缩:
(16 + 4 + 8 + 4(padding)) + (24+ 8*3) +(16 + 8) * 3 = 152bytes

开启压缩:

(12 + 4 + 4 + 4(padding)) + (16 + 4*3 +4(数组对象padding)) + (12+8+4(B对象padding))*3= 128bytes

再看一个有意思的例子

import net.sourceforge.sizeof.SizeOf;

public class MemoryCalculation {
	static class B {
			int a;
			int b;
		}
	static class C {
			int ba;
			B[] as = new B[3];
		}
	public static void main(String[] args) {
		System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(new C())))	;			
	}
}

未开启压缩:
(16 + 4 + 8 + 4(padding)) + (24+ 8*3) + 0 = 80 bytes

问:为什么这里B对象所占内存为0呢?
答:因为创建对象时,只分配数组as的引用的内存,所指向的对象内存还未指定,即数据未初始化,此时所占内存为0,而前面的例子数组中所指的对象在构造函数中已初始化.


心得:

  1. 对这个学习主要是让自己对java内存中对象的布局和所占大小有个了解
  2. 发现对象中方法是不占用内存的

参考链接:

  1. https://blog.csdn.net/ykdsg/article/details/12080071.
  2. https://www.cnblogs.com/magialmoon/p/3757767.html.

资源下载:

java对象内存到底占用多少例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骇客之技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值