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

在这里咱们将经过几个有趣的例子,来演示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);

相关文章
相关标签/搜索