一个对象到底占多大内存

最近在做一个小项目,需要把所有数据刷到内存中,避免采用redis或者其他内存数据库需要多次IO,数据大约9万条,因此要估计下大概需要耗费多少内存,以评估可以在server上部署多少个应用,突然有点懵,期初都是通过Runtime.totalMemory-Runtime.freeMemory来计算,但是这样似乎并不是很好,下面我们来分析分析一个对象到底占用多少内存。
先看一个表:
[table]
|类型 |未压缩(字节)|压缩(字节)
|boolean | 1|1|
|byte | 1|1|
|short | 2|2|
|char | 2|2|
|int | 4|4|
|float | 4|4|
|long | 8|8|
|double |8|8|
| reference |8|4|
|数组| 24|16|
[/table]
以上数据受到jvm参数压缩未压缩(UseCompressedOops)设定影响,这是基础。

我们再来看看Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding),对于padding,是因为占用字节数必须是8的倍数,你可以简单认为是凑数,因为因此内存占用也要从这几方面考虑。比如我们有一个类

class A{
int a;
}

头对象未压缩是16字节,压缩是12字节,因此:
未压缩:16(头对象)+4(a)+4(padding)=24字节
压缩:12(头对象)+4(a)=16字节
再看如下代码

class A{
int a;
Integer b;
}


因为 b是对象的引用,需要占用8个字节,因此
未压缩:16(头对象)+4(a)+8(b)+4(padding)=32字节
压缩:12(头对象)+4(a)+8(b)=24字节

我们再分析下数组,数组是个特殊的对象,64位机器上,数组对象的对象头占用24个字节,启用压缩之后占用16个字节。之所以比普通对象占用内存多是因为需要额外的空间存储数组的长度。
比如 Integer[0],长度为0,只有头对象,因此是24或者16
再比如Integer[3]
未压缩:24+8*3=28
压缩:16+4*3+4(padding)=32,你也应该知道Integer[4]在压缩下还是32 :D
最后再看一段代码:


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();
}
}
}


我们先来看下这个对象的内存结构吧:

[img]http://dl2.iteye.com/upload/attachment/0101/0632/5ed0fbcb-8b45-3ead-8bdd-7419394439e8.png[/img]

未压缩:
3个B实例:(16(头对象)+4(a)+4(b))*3=72
数组对象:24(头对象)+8(B引用)*3=48
C实例:16(头对象)+4(ba)+8(as引用)+4(padding)=32
压缩:
3个B实例:(12(头对象)+4(a)+4(b)+4(padding))*3=72
数组对象:16(头对象)+4(B引用)*3+4(padding)=32
C实例:12(头对象)+4(ba)+4(as引用)+4(padding)=24

因此一个c实例占用空间为:
未压缩:72+48+32=152
压缩:72+32+24=128

这就是对象占用空间的分析过程。

当然了,现实中,我们不可能去一个一个对象分析内存占用情况,那么代码如何实现呢,我们可以参考这篇博客:
[url]http://brandnewuser.iteye.com/blog/2113828[/url]

此片博客是借鉴别人博客以及我个人理解,欢迎大家拍砖。
借鉴博客位置:[url]http://www.cnblogs.com/magialmoon/p/3757767.html[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值