1. 内存泄漏引起的原因
内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会提示你Out of memory。
Java内存泄漏的根本原因是什么呢?长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收,这就是Java中内存泄漏的发生场景。
具体主要有如下几大类:
1、静态集合类引起内存泄漏:
像HashMap、List等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被List等引用着。
2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。
给Set集合中添加一个对象person,然后将person的age属性改变,调用remove()方法将不起作用,因为对象的hashCode()值发生变化。此时删除不掉就会发生内存泄漏
3、各种连接
如果不调用显示的 close() 方法,将会导致内存泄漏
4、单例模式
不正确使用单例模式是引起内存泄漏的一个常见问题,单例对象在初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部的引用,那么这个对象将不能被JVM正常回收,导致内存泄漏
class A{ public A(){ B.getInstance().setA( this ); } .... } //B类采用单例模式 class B{ private A a; private static B instance= new B(); public B(){} public static B getInstance(){ return instance; } public void setA(A a){ this .a=a; } //getter... }
显然B采用singleton模式,它持有一个A对象的引用,而这个A类的对象将不能被回收。想象下如果A是个比较复杂的对象或者集合类型会发生什么情况