如何防止java中的內存泄漏

前些天緊急出版本,發現一個內存泄漏問題,程序每次註銷都會有大量的對象沒有釋放,在
註銷登陸成功後,又會重新生成一個相同的對象。這樣,在做界面自動化測試的過程中,系統
頻繁註銷,登陸,再註銷。這樣如此反覆多次,會必然導致java這個進程的內存溢出OutOfMemory。

拿到問題,用JProfile把程序跑起來,查到具體泄漏的對象,然後進行詳細的分析。
發現兩個地方存在嚴重的泄漏:
1 某對象在創建,初始化的過程會創建一個線程,這個線程專門處理和計算機串口的通訊。
代碼如下:
package example;

/**
 * @author zLan1028
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class MemoeryTest
{
 
 public static void main(String[] args)
 {
  MemoeryTest test = new MemoeryTest();
  test.init();
  
  test = null;
  //do other something
 }
 
 public void init()
 {
  thread.start();
 }
 
 private Thread thread = new BasicThread ();
 boolean exit = false;
 class BasicThread  extends Thread()
 {
  List lstData = new LinkedList();
  public void run()
  {
   while(!exit)
   {
    synchronized(lstData)
    {
     if (lstData.isEmpty())
     {
      lstData.wait();
     }
     writeDataToSerialPort((String)lstData.removeFirst());
    }
   }
  }
  
  private void writeDataToSerialPort(String str)
  {
   //write data to serialPort
  }
 };
}
請大家看,在test對象被置位null後,是否這個對象會把垃圾回收器進行自動回收?
咋一看,應該會,這個對象已經沒有其它引用存在。其實不然,因爲這個對象中創建了一個內部類。
而在java中,內部類會自動獲得一個對外部類的對象引用,而在釋放test對象時,沒有去把它內部創建的線程對象,
所以這個線程對象在程序退出前會一直存在,所以它會一直保持對外部test對象的引用,這樣,每創建一個MemoeryTest
對象,都會存在一個線程對象泄漏,而且一個MemoeryTest對象泄漏。這樣時非常危險的。
如果只對這個對象進行初始化,而在程序註銷時沒有對創建的線程資源回收,則這個問題可以避免。
代碼如下:
在MemoeryTest 對象中增加一個 public void close()方法,在每次釋放MemoeryTest 對象時,主動調用close方法釋放資源。

 public void close()
 {
  try {
   exit = true;
   thread.interrupt();
   thread.join();
  } catch (Exception e)
  {
   e.printStackTrace(System.out);
  }
 }

一點積累,如有錯誤之處,還請各位大俠指導。歡迎郵件交流:[email protected].

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章