有趣的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);

相關文章
相關標籤/搜索