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的地方,需要改进。