区别:
内存泄漏(memory leak):内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏。
内存溢出(out of memory):简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出。
内存泄漏的根本原因即解决方法
根本原因:内存泄漏的根本原因是长生命周期的对象持有短生命周期对象的引用,尽管短生命周期的对象已经不再需要,但由于长生命周期对象持有它的引用而导致不能被回收。
以发生的方式来分类可分为四类:
-
常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
-
偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
-
一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。
-
隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。
解决方法建议:
-
尽早释放无用对象的引用。
-
避免在循环中创建对象。
-
使用字符串处理时避免使用String,应使用StringBuffer。
-
尽量少使用静态变量,因为静态变量存放在永久代,基本不参与垃圾回收。
内存溢出的原因以及解决方法
引起内存溢出的原因有很多种,常见的有以下几种:
-
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
-
集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
-
代码中存在死循环或循环产生过多重复的对象实体;
-
使用的第三方软件中的BUG;
-
启动参数内存值设定的过小。
内存溢出的解决方案:
-
第一步,修改JVM启动参数,直接增加内存。
-
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
-
第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。
-
第四步,使用内存查看工具动态查看内存使用情况。