在这里咱们将经过几个有趣的例子,来演示Java对象序列化缓存问题。下面这个程序很是神奇,用了不到4秒的时间就向个人硬盘上输出了1000TB的数据。不要怀疑你看错了,确实是不到4秒时间就输出1000TB的数据,不相信你也能够在你的电脑上运行一下这个程序。若是你的硬盘不够大也不用担忧,Java彻底能够本身解决硬盘容量问题。这个例子对你的电脑惟一的要求就是必须有256M以上的内存,而且要设置执行参数为-Xmx256m。相信如今没有谁的电脑内存是不够256M的。java
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;it
7. byte[] data = new byte[100 * 1024 * 1024];io
8. ObjectOutputStream out = new ObjectOutputStream(编译
9. new BufferedOutputStream(ast
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
前面的例子咱们反复的将同一个数组写出到文件中,可是并无修改数组的内容。下面的例子咱们将每次写出内容不一样的数组。由于Arrays.fill()的执行效率比较低。因此咱们只写出256个大数组。
47.import java.io.*;
48.import java.util.Arrays;
49.
50.public class ModifiedObjectWriter {
51. public static void main(String[] args) throws IOException {
52. byte[] data = new byte[10 * 1024 * 1024];
53. ObjectOutputStream out = new ObjectOutputStream(
54. new BufferedOutputStream(
55. new FileOutputStream("smalldata.bin")
56. )
57. );
58. for (int i = -128; i < 128; i++) {
59. Arrays.fill(data, (byte) i);