Java記憶體洩露的原因

長風破浪發表於2015-03-14

Java記憶體洩露的原因

1、靜態集合類像HashMap、Vector等的使用最容易出現記憶體洩露,這些靜態變數的生命週期和應用程式一致,所有的物件Object也不能被釋放,因為他們也將一直被Vector等應用著。

    這種情況可以通過remove clear方式釋放物件,沒有問題。

2、資料庫的連線沒有關閉情況,包括連線池方法連線資料庫,如果沒有關閉ResultSet等也都可能出現記憶體洩露的問題。

    這是程式碼中經常出現的問題。

3、內部類和外部類的引用容易出現記憶體洩露的問題;監聽器的使用,java中往往會使用到監聽器,在釋放物件的同時沒有相應刪除監聽器的時候也可能導致記憶體洩露。

    我認為此說法是不準確, 及時將物件設定為null可以加快記憶體回收,但並不代表記憶體不可達或者洩露,我們使用一個例子來驗證下

    

package testawt;

import java.io.Console;
import java.util.Scanner;
import java.util.Vector;

class person
{
    public String name;
    public String age;
    private hand  handhello;
    public person ()
    {
        handhello=new hand(this);
    }
    public void sayhello()
    {
        handhello.Shake();
    }
    public void finalize()
     {
         System.out.println("gc person!");
     }
}
class hand
{
    private person per;
    public hand(person per)
    {
        this.per=per;
    }
    public void Shake()
    {
        System.out.println("Shake!");
    }
    public void finalize()
     {
         System.out.println("gc hand!");
     }
}

public class testm {

    private static Scanner in;
    public static void main(String[] args) 
    {
        Vector<person> v = new Vector<person>();  
        for (int i = 1; i<20; i++)
        {
            person o = new person();
            v.add(o);
        }
        v.clear();
        System.gc(); 
        //所有物件釋放了
        in = new Scanner(System.in);  
        int a = in.nextInt(); 
        for (int i = 0; i < 10; i++)   System.out.println(a+i);
    }

}

    person和hand存在相互引用。但是強制呼叫gc ,能夠回收記憶體。
gc person!
gc hand!
gc person!
gc hand!
gc person!

3、大量臨時變數的使用,沒有及時將物件設定為null也可能導致記憶體的洩露

    我認為此說法不準確,及時將物件設定為null可以加快記憶體回收,但並不代表記憶體不可達或者洩露,如果你覺得自己使用了大量的臨時變數,可以自己強制執行一次System.gc();

   

import java.io.Console;
import java.util.Scanner;
import java.util.Vector;

class person
{
    public String name;
    public String age;
    public hand  handhello;
    public void finalize()
     {

         System.out.println("gc person!");
     }

}
class hand
{
    public void hello()
    {
        System.out.println("hello!");
    }
    public void finalize()
     {
         System.out.println("gc hand!");
     }
}

class footer
{
    public void walk()
    {
        System.out.println("walk!");
    }
    public void finalize()
     {
         System.out.println("gc footer !");
     }
}

public class testmain {

    private static Scanner in;

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        Vector<person> v = new Vector<person>();
        
        for (int i = 1; i<20; i++)
        {
            person o = new person();
            o.handhello=new hand();
            v.add(o);
            
            footer f=new footer();
            f.walk();
            //o = null; 
        }
        v.clear();
        System.gc(); 
        //所有物件釋放了
        in = new Scanner(System.in);  
        int a = in.nextInt(); 
        for (int i = 0; i < 10; i++)   System.out.println(a+i);
    }

}

  執行結果

gc footer !
gc hand!
gc person!
gc footer !
gc hand!
gc person!

 

相關文章