我通过检查字节数组使用ByteArrayOutputStream的时间来测量对象的大小。 在做的时候:
System.out.println(Utils.getObjectSize(new Integer(123123)));
System.out.println(Utils.getObjectSize(new Point(123, 123)));
他们返回81和51。
我相信Point由两个原语组成,但这似乎不是原因。
Utils.getObjectSize的代码I:
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(object);
objectStream.close();
return byteStream.toByteArray().length;
修改
我表示自己错了。我其实想知道为什么他们在流中占用更多的尺寸。答案 0 :(得分:8)
从字符串java.lang.Integer
开始,java.lang.Number
和value
出现在Integer
的序列化结果中。这应该暗示为什么序列化大小与对象成员的关系不是很好。
以下是列出的结果字节数组的一些内容:http://ideone.com/ragKZ
import java.awt.Point;
import java.io.*;
class Test {
public static byte[] getBytes(Object object) throws IOException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(object);
objectStream.close();
return byteStream.toByteArray();
}
public static void main(String[] args) throws IOException {
byte[] iBytes = getBytes(new Integer(123123));
System.out.println(new String(iBytes, 8, 17)); // "java.lang.Integer"
System.out.println(new String(iBytes, 39, 5)); // "value"
System.out.println(new String(iBytes, 48, 16)); // "java.lang.Number"
// ...
byte[] pBytes = getBytes(new Point(123, 123));
System.out.println(new String(pBytes, 8, 14)); // "java.awt.Point"
// ...
}
}
答案 1 :(得分:7)
您查找对象大小的方法实际上并不能衡量他们占用内存中的空间。
Point
实际上会占用更多内存而不是Integer
(对于4字节对齐的JVM; 8字节对齐它们将是相同的) - 它只是发生序列化到较小的大小,可能是由于继承层次结构。
答案 2 :(得分:5)
整数较大以序列化,因为其父Number
是可序列化的。如果打印对象序列化中的所有文本字节,则获得
....sr..java.lang.Integer.......8...I..valuexr..java.lang.Number...........xp....
但是,Point的父级不是Serializable,也没有序列化。
....sr..java.awt.Point...r4~.&...I..xI..yxp...{...{
此外,Integer的字段名称更长(稍微)
byte[] bytes = byteStream.toByteArray();
for(int i=0;i<bytes.length;i++) {
char ch = (char) bytes[i];
if (ch >= ' ' && ch < 127)
System.out.print(ch);
else
System.out.print('.');
}
System.out.println();
您正在使用的方法查看Object序列化作为byte []的大小,而不是内存中的大小。标准的Java序列化效率不高。
整数可能消耗16 + 4个字节,而Point可能消耗16 + 2 * 4个字节。但是,由于许多JVM在8字节边界上分配,您可能会发现它们消耗的内存量相同。
Integer更大的序列化原因是Java不仅序列化了Object,还将其父序列化,包括列出它们的内容。
答案 3 :(得分:2)
当您将对象序列化为流时,您正在测量对象的大小。这与内存中对象的大小不同。