JAVA中内存泄露和内存溢出

Posted qimox1314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA中内存泄露和内存溢出相关的知识,希望对你有一定的参考价值。

一、为什么要了解内存泄露和内存溢出

1.内存泄漏一般是程序员编写的代码有误导致的,了解内存泄漏的情况可以避免不必要的内存泄漏,让程序员提高自己编码水平。

2.通过了解内存溢出常见情况,可以快速准确地找到问题所在,缩短解决问题的时间。

二、内存泄漏和内存溢出的概念区分

1.内存泄漏,指的是,程序动态分配内存给一些临时对象,但是这些临时对象却没有GC所回收,始终占内存,即使没用了也始终占着内存,这就是内存泄漏。

2.内存溢出,指的是,没有被分配到足够的内存而导致的错误。

 

注意:看来内存泄漏是可能导致内存溢出的一种原因,并不是唯一原因。

 

三、内存泄漏的几种场景:

1.生命周期较长的对象中存了生命周期短的对象

这是内存泄漏的场景中最常见的一种,例如,在全局静态map中存了局部变量没有清空操作,随着时间的推移,map越来越大,因此造成内存泄漏。

 

2.修改了HashSet中对象计算哈希值的字段

当对象存入HashSet集合以后,就不能修改计算哈希值的字段了,否则修改后的哈希值与最初存入的哈希值就不同了。在这样的情况下,即使是在contains方法中使用该对象的当前引用作为参数也是找不到该对象的。这样就无法删除HashSet集合中的这个对象,因此导致内存泄漏。

 

3.机器的连接数和关闭时间设置

长时间开着非常耗费资源的连接也会造成内存泄漏。

四、内存溢出的几种情况:

1.方法区内存溢出(outOfMemoryError:permgem space)

    在jvm规范中,方法区主要存放的是类信息、常量、静态变量等。

 

  所以如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出,一般该区发生内存溢出时的错误信息为:

 

      outOfMemoryError:permgem space

2.线程栈溢出(java.lang.StackOverflowError)

       线程栈时线程独有的一块内存结构,所以线程栈发生问题必定是某个线程运行时产生的错误。

    一般线程栈溢出是由于递归太深或方法调用层级过多导致的。

    发生栈溢出的错误信息为:

      java.lang.StackOverflowError

五、避免内存泄漏和内存溢出的几种方法:

1、尽早释放无用对象的引用

2、使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域

3、尽量少用静态变量,因为静态变量存放在方法区,方法区基本不会被垃圾回收

4、避免在循环中创建对象

5、开启大型文件或从数据库一次拿了太多的数据很容易造成内存溢出,所以在这些地方要大概计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。 

以上是关于JAVA中内存泄露和内存溢出的主要内容,如果未能解决你的问题,请参考以下文章

Java:内存泄露和内存溢出

Java学习---内存泄露与溢出的区别

如何排查Java内存泄露

如何排查Java内存泄露

内存泄露与内存溢出

内存溢出和泄露