场景: 从大文件中逐行读取数据导入mysql数据库,3G纯文本,半结构化数据需要程序分析
问题:文件分析到一定行数出现异常(outOfMemory java heap space)
猜测:
1. 是不是程序将文本逐行加入到了内存,使得StringBuffer线性增加,导致内存溢出;
2. while循环中可能存在new语句,导致不断创建了某个类的实例(其实没有想到,最后解决问题发现的)。
关键思路:猜测1是最有可能的,但是检查程序后并未发现问题。需要知道JVM内存究竟被哪些数据占用
解决办法:
1. 寻找JVM内存检测工具(一类是JDK自带的内存分析工具,包括Jmap\Jhat\Jstat,但是并不好用;另一类找到了JProfiler, 独立的JVM运行时各种参数检测工具 );
2. 使用JProfiler工具检测程序运行时内存中加载的类实例以及占用的内存空间;
3.发现JDBC4ResultSet和StatementImpl生成了大量实例,数量一直在增加,没有被销毁,并且占据了近700M的内存,其他的类实例也会占用一定空间,但是数量都是有增有减,也就是对象会被销毁。
4. 猜测可能是while循环中不断创建了Statement对象,仔细检查程序果然如此。将Statement对象创建语句移除循环,测试OK了。
备注:
1. 拆解程序封装为多个方法可以增加程序的逻辑性,但是要注意在while循环中逐层调用方法中是否包含new语句(对象创建),如果包含new语句会导致循环创建对象,在大数据量情况下,直至堆空间溢出。此时需要在循环外创建对象,作为参数传入。
2. 大数据量导入数据库时,数据库日志如果开启的话会导致数据库日志文件不断增大,磁盘空间耗尽时将不能再导入数据。
3. 如果某些场景需要通过检测JVM调试程序时,建议使用JProfiler工具,非常好用。
阅读(5388) | 评论(0) | 转发(0) |