2012-04-24 100 views
1

我有一個適用於CSV文件的swing應用程序。它逐行讀取完整文件,計算一些所需的統計數據並顯示輸出。 輸出屏幕的上半部分按JTable中的順序顯示文件中的每條記錄,下半部分顯示基於該數據計算的統計信息。問題是JVM佔用的內存比文件大小多4倍。 (在處理86MB文件堆區域時使用377 MB空間 - 使用jVisualVM檢查內存使用率)。在Java中閱讀大文件

注:

  1. 我已經使用LineNumberReader讀取文件

  2. 對於閱讀每一行的readLine((東陽的具體要求,我如果在內存使用有助於改變它))被使用,然後.split(',')該行的字符串被稱爲該記錄的單個字段。

  3. 將每個記錄存儲在Vector中以便在JTable中顯示,而其他統計信息存儲在JavaBean類中的HashMap,TreeMap和摘要數據中。還有一個圖是使用JFreeChart繪製的。

請建議減少內存利用率,因爲我需要處理2GB文件。

+0

要說清楚,你是說你需要將整個2GB文件存儲在一個Vector中,並將其顯示在一個JTable中? – NPE 2012-04-24 17:37:30

+0

你可以用一個8GB的堆來完成它,或者你可以只加載你需要顯示的那部分文件。 – 2012-04-24 17:40:25

+0

是的,我想在內存中的2GB文件,但它不應該4倍的空間。 – Rony 2012-04-24 17:43:20

回答

0

使用最佳實踐來升級你的程序

  1. 寫多線程程序來獲得更好的CPU利用率。
  2. 設置堆的最小和最大堆大小以更好地使用RAM。
  3. 使用正確的數據結構和設計。
+0

CPU利用率不是我的問題,但內存利用率是。 – Rony 2012-04-24 17:45:31

+0

http://java.sun.com/performance/reference/whitepapers/tuning.html我希望這會對你有所幫助:) – 2012-04-24 17:49:10

1

嘗試給OpenCSV一槍。它只在使用readNext()方法時存儲最後一個讀取行。對於大文件,這是完美的。

從他們的網站,以下是它們所支持的功能:在報價元素每行值

  • 忽略逗號

    • 任意數字

    • 處理與嵌入的回車報價條目返回(即跨越多條線的條目 )

    • 個配置分離器和引號字符(或使用合理 默認值)

    • 閱讀所有條目一次,或使用迭代器風格模型

    • 從string []創建CSV文件(即。嵌入式 引號字符的自動轉義)

  • 0

    每個Java對象都有a memory overhead,所以如果你的字符串是真的很短,這可以解釋爲什麼你會得到你的文件大小的4倍。你還必須計算Vector的大小和它的內部。我不認爲Map會提高內存使用率,因爲Java字符串已儘可能地指向內存中的相同地址。

    我認爲你應該修改你的設計。鑑於您的要求

    輸出畫面的上半部分顯示的每個記錄從文件中的JTable 秩序,而下半部分顯示基於 數據

    你並不需要計算統計將整個文件存儲在內存中。你需要完全讀取來計算你的統計數據,這當然可以使用非常少量的內存來完成。關於JTable部分,這可以通過多種方式完成而不需要需要2GB的堆空間用於您的程序!我認爲當有人想把CSV保存在內存中時一定會出現問題! Apache IO LineIterator

    +0

    顯示完整文件是需求的一部分! – Rony 2012-04-25 18:25:47

    +0

    顯示文件並將其保存在內存中是兩件完全不同的事情 – Raffaele 2012-04-25 18:27:13

    0

    增加JVM堆大小(-Xms和-Xmx)。如果你有記憶,這是最好的解決方案。如果你無法做到這一點,你需要找到一種妥協方案,它將結合數據模型和演示(GUI)的變化,通常會導致代碼複雜性的增加和bug的可能性。

    1. 嘗試修改您的統計信息算法,以便在數據正在讀取時完成其工作,並且不要求所有數據都存在於內存中。您可能會發現接近統計數據的算法就足夠了。
    2. 如果您的數據包含許多重複的字符串文字,請使用HashSet創建緩存。請注意,緩存因內存泄漏而臭名昭着(例如,在加載不同文件之前不會清除它們)。
    3. 減少圖表上顯示的數據量。具有大量數據的圖形在同一像素處或附近顯示許多點是很常見的。考慮通過合併x軸上相同位置處或附近的多個值來截斷數據。例如,如果您的數據集包含2,000,000個點,則它們中的大多數將與其他附近的點重合,因此您的基礎數據模型不需要存儲所有內容。
    4. 請注意信息過載。如果您的JTable包含2GB的數據,那麼對用戶來說是否有意義?也許你應該對錶格進行分頁,並且一次只能從文件中讀取1000個條目進行顯示。
    5. 我很猶豫,建議這樣做,但在加載過程中,您可以將CSV數據轉換爲文件數據庫(如cdb)。您可以在轉換過程中累積統計數據並存儲圖形的一些數據,並使用數據庫按照上述建議一次爲JTable快速讀取一頁數據。