Java中的对象有多大?


习惯了C与语言中精确计算一个结构体,一段数组的所占空间,在使用Java时就有些心里没底。虽然知道Integer比int要大,到底大多少?知道String比char[]要大,到底大多少?我甚至一度认为这是与JVM的GC相关的动态数字。 看了几篇针对性的文章,并做实验,有了明确的认识。

归纳成以下几个数字化的结论

  • 一个Object需要8字节的housekeeping
  • 一个Object最终占用的字节数要向8字节对齐,即是8的倍数
  • Array一是种特殊的Object,一个Array需要8字节的housekeeping+4字节的length  
  • 一个char占用2个字节
关于String,先看一下String的定义

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

一个空的String所占用的字节数, 共计40bytes。一个字符都没写,40bytes先用去了。 如果写入10个char,那就是占用40+10*2=60bytes。也由此可见,写入char的长度多大,越可以摊薄每一个char所占用的空间,毕竟这个40bytes的启动成本太重了。

  • housekeeping        8bytes
  • char value[]             4+12(reference+itself) = 16bytes
  • offset/count/hash   3*4=12bytes
  • padding                   4bytes

举例,在实际工作中,经常遇到一些错误的实践,或者说省事儿的实践,就是在进行类型定义时,一切皆String。虽然性能优化不是最初该考虑的事情,但有时很快就会遇到不断调大Xmx,直至崩溃的场景。这里做一个实验,并通过JProfile来观察内存的使用情况。

  • String数组
String[] number_array = new String[ARRAY_SIZE];
for(int i=0; i<ARRAY_SIZE; i++){
	number_array[i] = new String(i+"");			
}
  • Integer数组
Integer[] number_array = new Integer[ARRAY_SIZE];
for(int i=0; i<ARRAY_SIZE; i++){
	number_array[i] = new Integer(i);			
}
  • int数组
int[] number_array = new int[ARRAY_SIZE];
for(int i=0; i<ARRAY_SIZE; i++){
	number_array[i] = i;			
}
  • 效果
  • 定义ARRAY_SIZE=8M
  • String数组: 494MB,平均每个String的空间约为66字节,符合预期。
  • Integer数组: 134MB,平均每个Integer的空间约为17字节,符合预期。
  • int数组: 40MB,(由于其内部实现为多段不连续的int[],因此加入多个array的空间成本),平均每个int的空间约为5字节,符合预期。
  • 494MB vs 40MB, 12倍左右的差距,非常明显的改善。虽然我们在定义如同HashMap的类型时,无法直接使用int,退一步讲,对于ID类型的Key,使用Integer也要比String有明显的空间压缩。
记住,一个空的String占40字节!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值