程式扎記: [ Java Essence ] 記憶中的那個東西 : 緊來倒垃圾 (哪些東西是垃圾 ?)

標籤

2011年3月3日 星期四

[ Java Essence ] 記憶中的那個東西 : 緊來倒垃圾 (哪些東西是垃圾 ?)

轉載自 這裡 
前言 : 
對於不再有用的物件,Java有自動回收資源的機制。哪些東西會被垃圾收集器(Garbage Collector)認定為不再有用的物件?簡單地說,無法被JVM中任何執行緒透過參考名稱循線參考到的物件,就是GC認定的垃. 

哪些東西是垃圾 : 
在啟動JVM之後,JVM中就會有一些執行緒,最基本的,就是執行程式進入點的主執行緒(main thread),基本上,這條執行緒是你要關心物件是否成為垃圾的起點. 
假設你有一個類別 : 

  1. public class Some {  
  2.     Some next;  
  3. }  
若是從程式進入點開始,有段程式碼如下撰寫 : 
  1. Some some1 = new Some();  
  2. Some some2 = new Some();  
  3. Some some1 = some2;  
執行到第二行時,主執行緒可以透過參考名稱所參考到的物件為 : 
 
執行到第三行時,是將some2參考的物件給some1參考,所以變成這樣 : 
 
這個時候,原先被some1參考的物件不再被任何名稱參考,透過主執行緒也不再可以參考到該物件,這個物件就是記憶體中的垃圾了,GC會自動找出這些垃圾並予以回收. 如果是建立的新執行緒,例如 : 
  1. public void someMethod() {  
  2.     Thread thread = new Thread() {  
  3.         public void run() {  
  4.             Some some = new Some();  
  5.             ...  
  6.         }  
  7.     };  
  8.     thread.start();  
  9. }  
在someMethod()執行過後,只要建立的執行緒還沒有離開run()方法,也就是執行緒還沒進入dead狀態,則該執行緒所參考的物件就一直還可以利用,也就不會被垃圾回收. 如果有段程式是這樣 : 
  1. Some some = new Some();  
  2. some.next = new Some();  
  3. some = null;  
在執行到第二行時,情況是這樣的 : 
 
而執行完成第三行後,情況變成如此 : 
 
這個時候,some原先所參考的物件,會被回收,而next所參考的物件亦因無法被循線參考到,也會被回收。所以同樣地道理,下面的程式碼中,陣列所參考到的物件全部都會被回收 : 
  1. Some[] somes = {new Some(), new Some(), new Some};  
  2. somes = null;  
 

如果是形同孤島的物件,例如 : 
  1. Some some = new Some();  
  2. some.next = new Some();  
  3. some.next.next = new Some();  
  4. some.next.next.next = some;  
  5. some = null;  
執行到第四行時,情況是這樣的 : 
 
執行完第五行後,情況變為如此 : 
 
這個時候形成孤島的右邊物件,將全部被GC給處理掉.

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!