內存泄漏小例子


1.

    public Object pop(){   
    if(size==0) throw new EmptyStackException();   
    return element[--size]; //短暫造成內存泄露   
    }   

 

上面的代碼每一次pop()的時候,Stack都會彈出一個元素,在沒有加入新元素之前,實際上仍然有一個引用element[x]指向了這個已經 彈出的對象,因此GC是不會對其進行垃圾回收的。只有push()新元素的時候使得element[x]=newObject,才會使得以前創建的對象有 可能被回收。應該把上面的pop()方法改成下面的代碼就安全多了:

public Object pop(){    
       if(element.length==size) throws EmptyStackException();    
       Object o=element[--size];    
       elements[size]=null;  //使得GC有機會回收這個對象     
       return o;    
}   

 

 

靜態集合類

在使用Set、Vector、HashMap等集合類的時候需要特別注意,有可能會發生內存泄漏。當這些集合被定義成靜態的時候,由於它們的生命周期跟應用程序一樣長,這時候,就有可能會發生內存泄漏,看下面代碼:

class StaticTest { private static Vector v = new Vector(10); public void init() { for (int i = 1; i < 100; i++) { Object object = new Object(); v.add(object); object = null; } } }

在上面的代碼中,循環申請了Object對象,並添加到Vector中,然后將對象設置為null,可是這些對象因為被Vector引用着,因此並不能被GC回收,因此造成了內存泄漏。因此,要釋放這些對象,還需要被它們從Vector刪除,最簡單的方法就是將Vector設置為null

集合里的對象屬性值被改變

看以下代碼:

public static void main(String[] args) { Set<Student> set = new HashSet<Student>(); Student s1 = new Student("Jack"); Student s2 = new Student("Mary"); Student s3 = new Student("Eason"); set.add(s1); set.add(s2); set.add(s3); System.out.println(set.size());//3 s2.setName("Jackson"); //修改屬性,此時s2元素對應的hashcode值發生改變 set.remove(s2); // remove不掉,造成內存泄漏 set.add(s2); // 添加成功 System.out.println(set.size());//4 }

在這個例子中,由於對象s2的屬性值被改變了,因此不能從set中刪除,所以set中會一直保持着s2的引用,不能被回收,造成了內存泄漏。

監聽器

在Java中,我們經常會使用到監聽器,如對某個控件添加單擊監聽器addOnClickListener(),但往往釋放對象的時候會忘記刪除監聽器,這就有可能造成內存泄漏。好的方法就是,在釋放對象的時候,應該記住釋放所有監聽器,這就能避免了因為監聽器而導致的內存泄漏。

各種連接

Java中的連接包括數據庫連接、網絡連接和io連接,如果沒有顯式調用其close()方法,是不會自動關閉的,這些連接就不能被GC回收而導致內存泄漏。一般情況下,在try代碼塊里創建連接,在finally里釋放連接,就能夠避免此類內存泄漏。

外部模塊的引用

調用外部模塊的時候,也應該注意防止內存泄漏。如模塊A調用了外部模塊B的一個方法,如:
public void register(Object o)
這個方法有可能就使得A模塊持有傳入對象的引用,這時候需要查看B模塊是否提供了去除引用的方法,如unregister()。這種情況容易忽略,而且發生了內存泄漏的話,比較難察覺,應該在編寫代碼過程中就應該注意此類問題。

單例模式

使用單例模式的時候也有可能導致內存泄漏。因為單例對象初始化后將在JVM的整個生命周期內存在,如果它持有一個外部對象(生命周期比較短)的引用,那么這個外部對象就不能被回收,而導致內存泄漏。如果這個外部對象還持有其它對象的引用,那么內存泄漏會更嚴重,因此需要特別注意此類情況。這種情況就需要考慮下單例模式的設計會不會有問題,應該怎樣保證不會產生內存泄漏問題。



文/zhutoulwz(簡書作者)
原文鏈接:http://www.jianshu.com/p/93b91ea18c28
著作權歸作者所有,轉載請聯系作者獲得授權,並標注“簡書作者”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM