有趣的Java对象序列化缓存问题

发表于:2010-5-17 13:00

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

#
java
#
Java

  在这里我们将通过几个有趣的例子,来演示Java对象序列化缓存问题。下面这个程序非常神奇,用了不到4秒的时间就向我的硬盘上输出了1000TB的数据。不要怀疑你看错了,确实是不到4秒时间就输出1000TB的数据,不相信你也可以在你的电脑上运行一下这个程序。如果你的硬盘不够大也不用担心,Java完全可以自己解决硬盘容量问题。这个例子对你的电脑唯一的要求就是必须有256M以上的内存,并且要设置执行参数为-Xmx256m。相信现在没有谁的电脑内存是不够256M的。

1.import java.io.*;
2.
3.public class SuperFastWriter {
4.    private static final long TERA_BYTE = 1024L * 1024 * 1024 * 1024;
5.    public static void main(String[] args) throws IOException {
6.        long bytesWritten = 0;
7.        byte[] data = new byte[100 * 1024 * 1024];
8.        ObjectOutputStream out = new ObjectOutputStream(
9.            new BufferedOutputStream(
10.                new FileOutputStream("bigdata.bin")
11.            )
12.        );
13.        long time = System.currentTimeMillis();
14.        for (int i = 0; i < 10 * 1024 * 1024; i++) {
15.            out.writeObject(data);
16.            bytesWritten += data.length;
17.        }
18.        out.writeObject(null);
19.        out.close();
20.        time = System.currentTimeMillis() - time;
21.        System.out.printf("Wrote %d TB%n", bytesWritten / TERA_BYTE);
22.        System.out.println("time = " + time);
23.    }
24.}

  编译之后,我们就可以执行这个程序了。

  java -Xmx256m SuperFastWriter

  可以看到类似以下的输出

  Wrote 1000 TB

  time = 3710

  你一定会非常奇怪,我用的到底是什么电脑。不仅输出的速度那么快,并且输出的内容完全超出了硬盘容量。每秒钟250 TB,简直是不可思议的事情。

  如果到硬盘上看一下输出的文件,会发现文件只有大概150M。这是因为当我们通过ObjectOutputStream输出一个对象的时候,ObjectOutputStream会将该对象保存到一个哈希表中,以后在输出相同的对象,都会只输出指针,不输出内容。同样的事情也发生在读取对象的时候。Java通过该机制达到最小化数据输入和输出的目的。下面的例子就演示了读取的过程。

25.import java.io.*;
26.
27.public class SuperFastReader {
28.    private static final long TERA_BYTE = 1024L * 1024 * 1024 * 1024;
29.    public static void main(String[] args) throws Exception {
30.        long bytesRead = 0;
31.        ObjectInputStream in = new ObjectInputStream(
32.            new BufferedInputStream(
33.                new FileInputStream("bigdata.bin")
34.            )
35.        );
36.        long time = System.currentTimeMillis();
37.        byte[] data;
38.        while ((data = (byte[]) in.readObject()) != null) {
39.            bytesRead += data.length;
40.        }
41.        in.close();
42.        time = System.currentTimeMillis() - time;
43.        System.out.printf("Read %d TB%n", bytesRead / TERA_BYTE);
44.        System.out.println("time = " + time);
45.    }
46.}

  在这个例子中,我们去读取刚才输出的文件。虽然文件只有150M左右,但是实际读取的时候,数据量应该是和写出的一样。程序执行时间只需要几秒时间。类似执行结果是:

  Read 1000 TB

  time = 2033

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号