最近需要从远程FTP读取一份约250W条数据的文件并解析入库,因资源有限,给应用分配的空间只有1GB。
原本的代码中,从远程获取文件流,并一次全部读取到内存中,解析后每500条插入一次数据库。
运行时直接抛出了java.lang.OutOfMemoryError: GC overhead limit exceeded异常
于是修改代码进行修改,将数据一次性读取到内存中,然后利用guava的Lists.partition方法进行切割,每1000条解析一次,然后入库。
通过jconsole进行监控,发现内存占用很多,并且GC时间较长。
将分批数量改为2000次后运行发现内存占用未减少,GC时间有所降低。
于是修改处理策略,将InputStream通过BufferReader进行行读取,每2000行解析一次,存入数据库。
通过jconsole进行监控
此时发现内存的使用率减少了很多,并且GC时间也有所减少。
将分批次数调整为1000次,再次测试。
发现GC时间更少了,而且程序运行时间从10分钟减低为了5分钟。
所以合理的读写数据以及合理的批量存储数据,能大大的提高程序的效率