分享
 
 
 

你知道数据大小吗?--不要花太多的功夫来隐藏类的成员(二)

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

结果:

让我们来对一些类使用这个工具,察看是否结果和我们预想的一样。

注意:以下的结果都是基于Windows平台的jdk1.3.1版本,并不能保证所有的平台或者jdk版本都得到相同的信息。

l java.lang.Object

这个所有对象的基类作为我们的第一个例子。对于java.lang.Object我们将得到:

'before' heap: 510696, 'after' heap: 1310696

heap delta: 800000, {class java.lang.Object} size = 8 bytes

所以,一个简单的Object对象要占用8个字节的内存空间,当然我们不能希望它所占的空间是0,因为每个实例都至少必须包含一些最基本的操作,比如equals(), hashCode(), wait()/notify()等。

l java.lang.Integer

我和我的同事都经常封装本地的int到Integer的实例中去,以便于我们能在集合的对象中使用它们,那样做到底要耗费多少内存呢?

'before' heap: 510696, 'after' heap: 2110696

heap delta: 1600000, {class java.lang.Integer} size = 16 bytes

这个16字节的结果比我们预想的要糟糕,因为一个int值恰好是4个字节,但是使用了Integer以后,多使用了3倍的空间。

l java.lang.Long

Long看起来应该比Integer使用更多的空间,可是事实并非如此:

'before' heap: 510696, 'after' heap: 2110696

heap delta: 1600000, {class java.lang.Long} size = 16 bytes

很明显,因为一种特别的JVM实现必须符合特定的CPU类型,所以事实上的对象大小在堆中所占的空间必须和低级的内存边界对齐。看起来一个Long是一个8字节的大小的Object对象加上8字节用来保存long值。相比之下,Integer就有4个字节没有使用的空间。所以,应该是JVM强制对象使用8字节作为字的边界。

l Arrays

接下来比较一些基本类型的数组,比较有指导意义,能够部分的发现一些隐藏的信息和证明另一些流行的诡计:使用一个size-1的数组封装基本类型来当作对象。通过修改Sizeof.main()来使用一个循环增加数组的长度。然后能够得到int数组:

length: 0, {class [I} size = 16 bytes

length: 1, {class [I} size = 16 bytes

length: 2, {class [I} size = 24 bytes

length: 3, {class [I} size = 24 bytes

length: 4, {class [I} size = 32 bytes

length: 5, {class [I} size = 32 bytes

length: 6, {class [I} size = 40 bytes

length: 7, {class [I} size = 40 bytes

length: 8, {class [I} size = 48 bytes

length: 9, {class [I} size = 48 bytes

length: 10, {class [I} size = 56 bytes

还有一些char数组:

length: 0, {class [C} size = 16 bytes

length: 1, {class [C} size = 16 bytes

length: 2, {class [C} size = 16 bytes

length: 3, {class [C} size = 24 bytes

length: 4, {class [C} size = 24 bytes

length: 5, {class [C} size = 24 bytes

length: 6, {class [C} size = 24 bytes

length: 7, {class [C} size = 32 bytes

length: 8, {class [C} size = 32 bytes

length: 9, {class [C} size = 32 bytes

length: 10, {class [C} size = 32 bytes

从以上可以看出,8个字节的边界很明显的表现出来了。同时,肯定包含不可避免的8个字节的Object头部,然后基本数据类型的数组占用其它的8个字节。使用int[1]和Integer相比,看起来不能提供任何的内存使用,除了可以作为一个同样数据的可变版本。

l 多维数组

多维数组有另外的一个惊人之处。开发者普遍的使用一个构造函数例如int[dim1][dim2]用于数字或者科学计算。在一个int[dim1][dim2]的数组实例中,每一个嵌套的int[dim2]都是一个对象,并且每一个对象都加上一个16字节的数组对象头。当我不需要一个三角的或者粗糙的数组,那个代表着纯粹的头部。当维数增加时,影响增加很大。举例来说,一个int[128][2]的实例占用3600字节,使用着246%的头部。在特别的例子byte[256][1]中,这个头部因素已经是19!和C/C++的解决方案相比,同样的语法不会增加这么多的内存消耗。

l java.lang.String

让我们来测试一个空串,现构造一个new String():

'before' heap: 510696, 'after' heap: 4510696

heap delta: 4000000, {class java.lang.String} size = 40 bytes

结果提供了一种相当不好的现象,就是一个空的String就要占用40字节的大小,足够用来保存20个字符了。

在我们使用包含内容的字符串以前,我们使用一个帮组方法来创建一个字符串。不过使用以下文字来创建:

object = "string with 20 chars";

将不会工作,因为所有的这样的对象操作将结束于同一个字符串实例。语言规范中明确表明如此的行为(java.lang.String.intern()),因此使用如下:

public static String createString (final int length)

{

char [] result = new char [length];

for (int i = 0; i < length; ++ i) result [i] = (char) i;

return new String (result);

}

在这样的创建函数以后,得到如此的结果:

length: 0, {class java.lang.String} size = 40 bytes

length: 1, {class java.lang.String} size = 40 bytes

length: 2, {class java.lang.String} size = 40 bytes

length: 3, {class java.lang.String} size = 48 bytes

length: 4, {class java.lang.String} size = 48 bytes

length: 5, {class java.lang.String} size = 48 bytes

length: 6, {class java.lang.String} size = 48 bytes

length: 7, {class java.lang.String} size = 56 bytes

length: 8, {class java.lang.String} size = 56 bytes

length: 9, {class java.lang.String} size = 56 bytes

length: 10, {class java.lang.String} size = 56 bytes

结果很明显的表明了字符串的内存增加轨迹。但是字符串要增加一个24字节的头部。对于非空的字符串,如果字符个数少于10个或者更少,这个增加的头部将消耗相对于有效的负载(2个字节对于每个字符,加上4个作为长度)在100%到400%之间变化。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有