为什么Point占用的内存少于Integer

时间:2011-05-09 08:52:04

标签: java memory

我通过检查字节数组使用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;

修改

我表示自己错了。我其实想知道为什么他们在流中占用更多的尺寸。

4 个答案:

答案 0 :(得分:8)

从字符串java.lang.Integer开始,java.lang.Numbervalue出现在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)

当您将对象序列化为流时,您正在测量对象的大小。这与内存中对象的大小不同。