如何知道Map对象的大小 请问各位大侠,在网络传输过程中,我用了一 个Map对象,现在想知道 这个对象在网络传输过程中的大小,这该怎么实现呀!!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.util.HashMap;import java.util.Map;import net.blogjava.frankiegao123.util.ByteUtil;public class HelloWorld { public static void main(String[] args) throws IOException { Map<String, String> map = new HashMap<String, String>(); map.put("123", "abc"); map.put("456", "def"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream ooo = new ObjectOutputStream(baos); ooo.writeObject(map); byte[] bys = baos.toByteArray(); // 长度需要减去 4 个字节:AC ED 00 05 // AC ED -- 魔法数字 // 00 05 -- 版本号 System.out.println(bys.length - 4); }} 有异议,ooo.write(int)得出的结果是0应该考虑实际占用多少字节。比如在JProbe Profiler中查看一个对象占用多少字节请参考http://javag.javaeye.com/blog/319286 public class Helloworld { public static void main(String[] args) throws IOException { Map<String, String> map = new HashMap<String, String>(); map.put("123", "abc"); map.put("456", "def"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream ooo = new ObjectOutputStream(baos); ooo.writeObject(map); byte[] bys = baos.toByteArray(); for(byte b : bys){ System.out.print(b); } System.out.println(); // 长度需要减去 4 个字节:AC ED 00 05 // AC ED -- 魔法数字 // 00 05 -- 版本号 System.out.println(bys.length - 4); }} 我的执行结果是:-84-1905115114017106971189746117116105108467297115104779711257-38-63-612296-473027001010811197100709799116111114730911610411410111510411110810012011263640000012119800016000211603495051116039798991160352535411603100101102120102请教一下 火龙果 老哥, // 长度需要减去 4 个字节:AC ED 00 05 // AC ED -- 魔法数字 // 00 05 -- 版本号AC ED 00 05 这个是怎么弄出来的?? 这是写是不正确的,除了序列化对象之外,还会增加一些额外的字节。你那个是结果是“0”的话,是因为你没有执行 flush,还在缓冲区中。 一个对象占用多少内存,在 Java 中的意义不大,就算了解了占用多少内存,你又能做什么呢?Java 是在 JVM 上运行的,JVM 占据系统的一块内存,之后再在这块内存上进行分配。在任务管理器中看到的 java.exe/javaw.exe 进程所占用的内存并不是应用程序占用的内存,而是 JVM 先行“霸占”的内存,这有点像 Windows Vista 及以后版本中的 SuperFetch 内存管理技术。JavaWorld 上有两篇文章,有兴趣的话可以去看看:Do you know your data size?http://www.javaworld.com/javaworld/javatips/jw-javatip130.htmlSizeof for Javahttp://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html 或许不应该叫“魔法数字”,魔法数字是《重构》一书中的概念,与这里的不关,呵呵。这里应该称为“魔数(magic number)”,魔数一般用于减少读取到垃圾数据的几率。像 Java 的 class 文件也有魔数,即 CA FE BA BE,类加载器加载字节码时,会先验证这 4 个字节,如果头 4 个字节不是这 4 个,那么下面也别做了,肯定不是个类文件,这样做的目的是可以加速错误的产生,不需要浪费无用功。像很多网络传输协议中也带有魔数,比如规定报文中使用 A0 A0 A0 A0 作为魔数,当收到消息时先判断魔数是否正确,如果不正确,可以认为这是一段垃圾数据,不需要处理。 这个问题很有意思啊假如:map.put("123", "abc");得到字节流的变化部分是:0 0 0 1 116 0 3 49 50 51 116 0 3 97 98 99 120假如:map.put("123", "abc");map.put("456", "def");得到字节流的变化部分是:0 0 0 2 116 0 3 49 50 51 116 0 3 97 98 99 116 0 3 52 53 54 116 0 3 100 101 102 120假如什么都不加:0 0 0 0 120由此可见,前四个字节是表示map的entry数量的,116 0 3 是某类分隔标识 120应该是结束标识但不知其余不变部分剩下的都表示什么-84 -19 0 5 115 114 0 17 106 97 118 97 46 117 116 105 108 46 72 97 115 104 77 97 112 5 7 -38 -63 -61 22 96 -47 3 0 2 70 0 10 108 111 97 100 70 97 99 116 111 114 73 0 9 116 104 114 101 115 104 111 108 100 120 112 63 64 0 0 0 0 0 12 119 8 0 0 0 16 很NB啊,学到了,magic number 火龙哥,这样会把HashMap中nonstatic nontransient的数据域的名字和类型名都计算进去吧,应该bys.length - 4应该不是真正堆中对象的大小吧。 Java线程问题 关于access数据库导入到SQL SERVER2005的问题 socket读取流在debug的不同表现 Java继承问题 看一个关于null的测试用例 运行一个关于ArrayList的例子,编译出错,不知是什么原因,请赐教。 JProgressBar有个问题。 javaGUI字体错误“口口” 请教高手 请教如何在weblogic6上deploy一个包含Applet的Web Applcation(.war)/谢谢/ Java可变参数列表 Java读取配置文件问题
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;import net.blogjava.frankiegao123.util.ByteUtil;public class HelloWorld { public static void main(String[] args) throws IOException {
Map<String, String> map = new HashMap<String, String>();
map.put("123", "abc");
map.put("456", "def");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream ooo = new ObjectOutputStream(baos);
ooo.writeObject(map);
byte[] bys = baos.toByteArray();
// 长度需要减去 4 个字节:AC ED 00 05
// AC ED -- 魔法数字
// 00 05 -- 版本号
System.out.println(bys.length - 4);
}
}
请参考http://javag.javaeye.com/blog/319286
Map<String, String> map = new HashMap<String, String>();
map.put("123", "abc");
map.put("456", "def");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream ooo = new ObjectOutputStream(baos);
ooo.writeObject(map);
byte[] bys = baos.toByteArray();
for(byte b : bys){
System.out.print(b);
}
System.out.println();
// 长度需要减去 4 个字节:AC ED 00 05
// AC ED -- 魔法数字
// 00 05 -- 版本号
System.out.println(bys.length - 4);
}
}
-84-1905115114017106971189746117116105108467297115104779711257-38-63-612296-473027001010811197100709799116111114730911610411410111510411110810012011263640000012119800016000211603495051116039798991160352535411603100101102120
102
请教一下 火龙果 老哥, // 长度需要减去 4 个字节:AC ED 00 05
// AC ED -- 魔法数字
// 00 05 -- 版本号AC ED 00 05 这个是怎么弄出来的??
这是写是不正确的,除了序列化对象之外,还会增加一些额外的字节。你那个是结果是“0”的话,是因为你没有执行 flush,还在缓冲区中。
http://www.javaworld.com/javaworld/javatips/jw-javatip130.htmlSizeof for Java
http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html
或许不应该叫“魔法数字”,魔法数字是《重构》一书中的概念,与这里的不关,呵呵。这里应该称为“魔数(magic number)”,魔数一般用于减少读取到垃圾数据的几率。像 Java 的 class 文件也有魔数,即 CA FE BA BE,类加载器加载字节码时,会先验证这 4 个字节,如果头 4 个字节不是这 4 个,那么下面也别做了,肯定不是个类文件,这样做的目的是可以加速错误的产生,不需要浪费无用功。像很多网络传输协议中也带有魔数,比如规定报文中使用 A0 A0 A0 A0 作为魔数,当收到消息时先判断魔数是否正确,如果不正确,可以认为这是一段垃圾数据,不需要处理。
假如:map.put("123", "abc");得到字节流的变化部分是:
0 0 0 1 116 0 3 49 50 51 116 0 3 97 98 99 120假如:
map.put("123", "abc");
map.put("456", "def");得到字节流的变化部分是:
0 0 0 2 116 0 3 49 50 51 116 0 3 97 98 99 116 0 3 52 53 54 116 0 3 100 101 102 120假如什么都不加:
0 0 0 0 120由此可见,前四个字节是表示map的entry数量的,116 0 3 是某类分隔标识 120应该是结束标识
但不知其余不变部分剩下的都表示什么-84 -19 0 5 115 114 0 17 106 97 118 97 46 117 116 105 108 46 72 97 115 104 77 97 112 5 7 -38 -63 -61 22 96 -47 3 0 2
70 0 10 108 111 97 100 70 97 99 116 111 114 73 0 9 116 104 114 101 115 104 111 108 100 120 112 63 64 0 0 0 0 0 12 119
8 0 0 0 16
火龙哥,这样会把HashMap中nonstatic nontransient的数据域的名字和类型名都计算进去吧,应该bys.length - 4应该不是真正堆中对象的大小吧。