读取文件导致的OOM文件

young 34 2024-11-23

最近需要从远程FTP读取一份约250W条数据的文件并解析入库,因资源有限,给应用分配的空间只有1GB。

原本的代码中,从远程获取文件流,并一次全部读取到内存中,解析后每500条插入一次数据库。

运行时直接抛出了java.lang.OutOfMemoryError: GC overhead limit exceeded异常

于是修改代码进行修改,将数据一次性读取到内存中,然后利用guava的Lists.partition方法进行切割,每1000条解析一次,然后入库。

通过jconsole进行监控,发现内存占用很多,并且GC时间较长。
file-oom-1
将分批数量改为2000次后运行发现内存占用未减少,GC时间有所降低。
file-oom-3
于是修改处理策略,将InputStream通过BufferReader进行行读取,每2000行解析一次,存入数据库。

通过jconsole进行监控
file-oom-2

此时发现内存的使用率减少了很多,并且GC时间也有所减少。

将分批次数调整为1000次,再次测试。
file-oom-4
发现GC时间更少了,而且程序运行时间从10分钟减低为了5分钟。

所以合理的读写数据以及合理的批量存储数据,能大大的提高程序的效率