您的位置:首页 > 编程语言 > Java开发

我碰到的Java heap space问题

2015-12-01 10:20 441 查看
java heap space

今天帮别人调bug,是一个读取文件的程序,之前文件不大的时候没出过这个错误,文件大了就出了

开始我以为是jvm内存配置问题,但是配置到最大依然无效(就那个在jdk那里写的一些参数-Xms200m -Xmx512m这两个参数的设置不要超过物理内存就可以了),百度搜索

java heap space 基本上都是告诉你这么做的,确实也能解决一部分问题。其实java heap space也确实是由两种问题造成的。

1、jvm内存分配太少

2、代码有问题

我碰到的问题就是代码有问题

错误代码大概是

while((line=rd.readLine())!null){//这里报错了
·····
······
······
DataMap d = new DataMap(XX,XX,XX);
list.add(d);

}

然后我觉得是这里的错误,改掉之后(add之后加一句d=null;并且把变量d的定义放外边了。错误解决)

DataMap d ;

while((line=rd.readLine())!null){//这里报错了
·····
······
······
d = new DataMap(XX,XX,XX);
list.add(d);
d = null;

}

这是一个典型的内存溢出错误,溢出原因是list中放入对象的引用又没有把变量手动置为空,这些变量就倒置了其对应的对象一直没有释放掉,一直消耗内存。

我们知道java的GC会回收那些没有被堆上的变量指向的对象(栈中的对象)。所以当你把d = null其实就是发出一个信号让GC抽时间(注意是抽时间,不是立刻)

回收调上面new的对象。
http://itindex.net/detail/51440-java-%E5%86%85%E5%AD%98-%E6%BA%A2%E5%87%BA这篇文章整理了对java heap space错误的排查过程。大家可以看看。

这个错误得出的结论是

重复利用的变量放到外边声明,用过的对象及时的通知GC去回收。

还有就是推荐文章中提到的造成内存溢出的问题要注意。

帮大家贴一下:

  一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;

 

  二)是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)

 

  三)是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)

 

  四)检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过10万多条了,就可能会造成内存溢出。所以在查询时应采用“分页查询”。

 

  五)检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。

 

  六)检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从

  而导致JVM没有及时回收而出现内存溢出。

  最后当你发现这些问题都没有但是依然出错误的时候,那么问题已经不是代码或者什么了。原因很可能是你操作的文件太大了,而是你要改变策略了。记得之前做个用poi
  把表中的结果导入到excel表中,当数据集超过一定量的时候也会出现这种情况。你需要对操作对象做处理了。当时我们的处理是分页一次拿出几万条分多次生成excel。。

所以面对这个问题分三步处理:

1.更改jvm内存配置参数

2.查阅代码找出很2的代码

3.改变策略
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内存溢出 java jdk jvm