Java - OutOfMemoryError - GC overhead limit exceeded And Java heap space

Java - OutOfMemoryError - GC overhead limit exceeded And Java heap space

因為寫了常駐程式,爬圖檔,每天約20萬到50萬筆的圖檔資料。

總共約有400萬筆的資料,雖然不多,

但已經讓我程式中途發生錯誤。

先求有再求好,爬圖沒事,但程式繼續加的情況下,多加了MySQL insert之後。

好多狀況就陸續出現,

中途當掉失敗的狀況有

OutOfMemoryError  GC overhead limit exceeded 及 OutOfMemoryError Java heap space

分別用不同方法解決

OutOfMemoryError  GC overhead limit exceeded 使用參數

java -jar -XX:-UseGCOverheadLimit javaJar.jar處理。

這個原因在於GC 花太多時間在做 garbage collect (預設是 98%), 而太少時間在做你程式原本要做的事 :

因為我使用多執行緒,而是一個任務結束後,立即塞新的任務處理,結果,每個任務後我都使用System.gc()

反而就造成了這個問題,

可見gc應該不是放在子執行緒裡。

應該由主執行緒控管,且主執行緒要gc的時間點,應該要有一定的時間間隔。

 

再來是

Java heap space

這我猜想應該是使用太多的ArrayList及HashMap,因為連到http的部分,每一筆資料我都要做回傳記錄,並且裡面我使用了ArrayList來做參數自動生成,

再來是MySQL我也用ArrayList做參數生成sql與指令,

在一天有80萬筆資料量,就等於有double或三倍以上的ArrayList,反而產生了許多heap,

決定把這兩個都寫死成一個String參數,並且sql也使用static,

雖然寫程式上是難維護一點點,但已經run很久了,應該是無所謂了,

但許多地方不再生成記憶體,或許會加快速度,的確也從原本的4倍速,加快到8倍至12倍,再來就是24倍。

的確有差,但時間久了,由於記憶體未釋放,導致又降低倍數。

這還要再研究,哪裡的記憶體未釋放,或用太多。

Java heap space 要使用

-Xms1024m -Xmx1024m 去處理, 但不見得有用。

所以還是要調整程式碼,看哪些使用ArrayList、Map的地方,需要改進。