2013-04-29 55 views
5

我有一個存儲發票的數據庫。我必須使用所有發票中的信息通過一系列算法爲任何給定的月份進行復雜的操作。檢索和處理這些操作所需的數據需要大量的內存,因爲可能會有大量的發票。當用戶要求這些計算的間隔時間長達幾年時,問題變得越來越嚴重。結果是我得到了一個PermGen異常,因爲看起來垃圾收集器在每個月的計算之間都沒有完成它的工作。在大數據處理期間是否有任何方法來釋放內存?

我一直在使用System.GC來提示GC來完成它的工作並不是一個好的做法。所以我的問題是,除此之外,還有其他方法可以釋放記憶嗎?你能強制JVM使用HD交換來臨時存儲部分計算嗎?

此外,我試圖在每個月的計算結束時使用System.gc,結果是CPU使用率高(由於垃圾回收器被調用)和合理的較低的內存使用。這可以完成這項工作,但我認爲這不是一個合適的解決方案。

+0

如果您向我們展示您的代碼片段,我們可以提供更好的指導。也許你的變量存在錯誤的範圍,因此存在太多時間。 – 2013-04-29 14:20:12

+1

根據您對數據執行的操作類型,直接使用數據庫執行這些操作可能會更快,而不是將數據加載到java中,創建對象並分配內存......雖然這不能解答您的問題,但如果你的操作主要是*移動*數字,*做一些計算*,*讀*和*寫* *那麼你的數據庫可以更快地執行這些操作,因爲它「*更接近源*」 – GameDroids 2013-04-29 14:28:56

回答

2

永遠不要使用System.gc()。它總是需要很長時間才能運行,並且通常不會做任何事情。

要做的最好的事情就是重寫代碼,儘可能減少內存使用量。你沒有解釋你的代碼究竟是如何工作的,但這裏有兩個想法:

  • 嘗試重新使用你自己爲每個月生成的數據結構。因此,假設您有發票清單,請在下個月重新使用該清單。
  • 如果您需要所有這些,請考慮在處理時將處理後的文件寫入臨時文件,然後在準備就緒時重新加載它們。
1

我們應該記得System.gc()沒有真正運行垃圾收集器。它只是要求做同樣的事情。 JVM可能會或可能不會運行垃圾收集器。我們所能做的只是爲垃圾收集提供不必要的數據結構。你也可以這樣做:

  1. 指定Null作爲任何數據結構使用後的值。因此沒有活動的線程將能夠訪問它(簡而言之,它爲gc)。
  2. 重複使用相同的結構,而不是創建新的結構。
相關問題