Java内存泄漏
1.定义
内存泄露是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成的内存空间的浪费称为内存泄露。内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会提示你Out of memory。
2.引起内存泄漏原因
2.1容器使用时引起内存泄漏
像HashMap、Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。
Vector arr = new Vector();
for(int i = 0;i < 100 ;i++){
Object o = new Object();
arr.add(o);
o = null;
}
这里内存泄露指的是在对vector操作完成之后,执行下面与vector无关的代码时,如果发生了GC操作,这一系列的object是没法被回收的,而此处的内存泄露可能是短暂的,因为在整个method()方法执行完成后,那些对象还是可以被回收。这里要解决很简单,手动赋值为null即可:
Vector arr = new Vector();
for(int i = 0;i < 100 ;i++){
Object o = new Object();
arr.add(o);
o = null;
}
//对arr的操作
arr = null;
//其他操作
像下面容器ArrayList的使用就会更快的发生内存泄漏
ArrayList al = new ArrayList[99999];
2.2各种提供close()方法的对象引起内存泄漏
比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,以及使用其他框架的时候,除非其显式的调用了其close()方法(或类似方法)将其连接关闭,否则是不会自动被GC回收的。其实原因依然是长生命周期对象持有短生命周期对象的引用。
Connection con = dataSource.getConnection();
像上面连接是数据库的代码,如果不关闭,也会引起内存泄漏,改成下面的就可以了
Connection con = dataSource.getConnection();
con.close();
2.3单例模式引起内存泄漏
单例模式,很多时候我们可以把它的生命周期与整个程序的生命周期看做差不多的,所以是一个长生命周期的对象。如果这个对象持有其他对象的引用,也很容易发生内存泄露。
2.4内部类和外部模块等的引用引起内存泄漏
内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。此外程序员还要小心外部模块不经意的引用,例如程序员A 负责A 模块,调用了B 模块的一个方法,
这种调用就要非常小心了,传入了一个对象,很可能模块B就保持了对该对象的引用,这时候就需要注意模块B 是否提供相应的操作去除引用。
2.4监听器引起内存泄漏
在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。