Chinaunix首页 | 论坛 | 博客
  • 博客访问: 191825
  • 博文数量: 19
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1062
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-10 15:52
个人简介

经历过才能真的感受,做一个靠谱的人!

文章分类

全部博文(19)

文章存档

2015年(1)

2013年(18)

我的朋友

分类: Java

2015-04-20 22:25:30

场景: 从大文件中逐行读取数据导入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工具,非常好用。
阅读(5369) | 评论(0) | 转发(0) |
0

上一篇:Linux里如何查找文件内容

下一篇:没有了

给主人留下些什么吧!~~