[讨论] java 类型所占用的字节数
xgj1988
2011-05-20
JVM好像写的是一个LONG 基本类型是 8个字节。Integer是4个字节。
那我现在得到的结果好像并非如此。。 import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.util.ArrayList; @SuppressWarnings("unused") public class Test { private static ArrayList<Integer> permGen = new ArrayList<Integer>(); private byte[] bytes = new byte[(1024 << 10) * 10]; public static void main(String[] args) throws Exception { String x = new String("123"); long y=4L; NullOutputStream out = new NullOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(y); System.out.println(out.size()); } private static class NullOutputStream extends OutputStream { int size = 0; public void write(int b) throws IOException { size++; } public void write(byte[] b) throws IOException { size += b.length; } public void write(byte[] b, int off, int len) { size += len; } public int size() { return size; } } } 我得到的结果是y是82.这个。但是对于String(123)可以得到10。这个和和预计的一样 首先String 是个对象,对象本身就是4个字节,加上"123".length()*2,可以得到10 。 但是对于y的long类型,结果是82,太让我出乎意料了。 |
|
xgj1988
2011-05-20
额。好像是方法调用错了。 用writeLong是4,感觉是引用所占的字节 ,先看看源代码。
|
|
RednaxelaFX
2011-05-20
嗯你这是典型的错误。我记得以前在哪帖里回复过的…啊啊那个也应该打捞到blog里的。
序列化之后的数据跟原本在JVM内的Java对象运行时的样子没有直接关系。 你测的数据只是序列化后数据的大小。那是符合Java序列化机制所规定的,而跟JVM规范没关系。 ================================================ 举个简单的一个例子来说明差别: Java说Java程序要用UTF-16作为内部编码来存储String的内容。那么运行时JVM内String里真正装字符串数据的可以是一个char[] (注意:但也可以不是char[];byte[]的实现也有,请看JDK 6 update 23里的j2se/src/share/altclasses/java/lang/String.java)。 但是ObjectOutputStream却是用UTF-8编码来输出字符串的。看writeUTF方法的描述。 ================================================ 所以说别用序列化的办法来看Java对象的大小。 非要从Java层面看的话,java.lang.instrument.Instrumentation.getObjectSize(Object objectToSize) 这个才是正道。 |
|
xgj1988
2011-05-20
3Q。以前真还没仔细研究过。这个
|