ObjectOutputStream的原始数组小于原始数组

时间:2016-02-25 19:10:34

标签: java arrays memory serialization memory-management

我有一个函数,它接受一个对象并将其转换为一个字节数组:

public static byte[] serialize(Object obj) throws IOException {
    try(ByteArrayOutputStream b = new ByteArrayOutputStream()){
        try(ObjectOutputStream o = new ObjectOutputStream(b)){
            o.writeObject(obj);
        }
        return b.toByteArray();
    }
}

当我在基本类型上使用此函数时,输出最终会大于同一基元的单个数组。

public static void main (String[] args) throws java.lang.Exception
{
    System.out.format("byte    single: %d,    array: %d\n", 
            serialize((byte)   1).length, serialize(new byte[]{1}).length);

    System.out.format("short   single: %d,    array: %d\n", 
            serialize((short)  1).length, serialize(new short[]{1}).length);

    System.out.format("int     single: %d,    array: %d\n", 
            serialize((int)    1).length, serialize(new int[]{1}).length);

    System.out.format("float   single: %d,    array: %d\n", 
            serialize((float)  1).length, serialize(new float[]{1}).length);

    System.out.format("double  single: %d,    array: %d\n", 
            serialize((double) 1).length, serialize(new double[]{1}).length);

}

这会产生:

byte    single: 75,    array: 28
short   single: 77,    array: 29
int     single: 81,    array: 31
float   single: 79,    array: 31
double  single: 84,    array: 35

这里发生了什么?为什么阵列更小?这是Ideone for the issue

2 个答案:

答案 0 :(得分:1)

servant处理原始数组的方式与其他对象不同。在序列化之前,您没有序列化基元,而是序列化它们,因此ObjectOutputStream变为int等。

对于数组,Integer只写下面的内容(我以ObjectOutputStream为例)

double

你在实验中观察到35个字节。

对于其他对象 - 如盒装基元 - 它使用更多空间,因为它必须存储更多的元信息。它必须存储它们的对象类型,并且对于每个成员它必须存储相同的信息 - 所以它有点递归。

如果您真的想了解详细情况,我建议您阅读1 byte // to mark it as array 22 bytes // for the class description 4 bytes // the length of the array 8 bytes // for the double (would be array.length * 8) is you have more elements 的{​​{3}}。

答案 1 :(得分:1)

这是因为Java对数组使用不同的编码,效率更高。如果序列化Byte,它会写入一个对象(稍后可能会引用它以便记录一个id),该对象具有类java.lang.Byte(同样具有id),其具有父级类java.lang.Number(也带有id),没有字段,Byte有一个字段叫做" value" (这是一个带有id的字符串),字节的值只使用一个字节。

一个byte []的内部名称为[B,它没有字段的父母,因此它更短。