【JAVA】谈谈内存泄露

版权声明:转载请注明 https://blog.csdn.net/qq_33591903/article/details/84191399

                                               谈谈内存泄露

应届生面试中,常常被问到内存泄露,比方说什么是内存泄露呀?造成内存泄露的情况等等。本菜今天就总结一下内存泄露方面的几点小知识。

一、什么是内存泄露

不再被使用的对象持续占据内存,造成内存浪费的情形称作内存泄露。这些对象被某些变量引用着,因此垃圾回收器无法回收它们。关于垃圾回收器如何判断对象的存活状态,请移步我的另外一篇文章【JAVA】如何判断对象已经死亡?

当然引用类型也会对对象的生命周期造成影响,我的另外一篇文章【JAVA】java中的四种引用


二、造成内存泄露的情形及对应解决方案

【1】长生命周期的对象持有短生命周期对象的引用,就很有可能造成内存泄露。 

长生命周期的对象往往和整个程序的生命周期相同,若是当它们持有短生命周期的对象的引用,尽管短对象不再被使用,也无法被垃圾回收器回收,因为垃圾回收器无法回收被强引用所关联的对象。

解决方案:

(1)像一些静态的集合类,它们的生命周期和整个程序相同,尽管放入集合中的元素不再需要,就算将元素强行置为null,但由于集合类持有它们的引用,这些元素占据的空间也得不到释放,那么在必要的时候,我们可以将集合类对象类型的变量置为null。

(2)单例模式中,单例与整个程序的生命周期一致,如果单例对象持有其他短对象的引用,也很容易造成内存泄露,这还得靠我们谨慎编码。

(3)又或是数据库连接对象(长生命周期),ResultSet与Statement对象(短生命周期),连接不再被使用时,需要调用其close()方法,释放长对象与短对象。同理,需要显式调用close()方法的长生命周期的对象还有Socket、IO流、Session等。


【2】非静态的外部类会隐式地持有外部类的一个强引用。

在Android中,如果在Activity内声明一个非静态的内部类,那么只要该内部类没有被回收的话,那么外部类Activity就无法被回收,Activity所关联的视图和资源也不会被回收,这样的内存泄露比较严重。

解决方案:

(1)将非静态内部类改为静态内部类,静态内部类属于类,因此不会依赖与外部类的实例,从而不持有外部类实例的引用。

(2)显式地声明非静态内部类持有外部类的一个弱引用,被弱引用关联的对象,在下一次垃圾回收器活动时,就会被回收。

 

 

猜你喜欢

转载自blog.csdn.net/qq_33591903/article/details/84191399