2013-11-23 49 views
1

我對如何利用Java的垃圾回收來處理不再使用的對象實例有點困惑。我有幾個問題:有關類實例的Java垃圾回收

在我的比賽,我產生大炮沒有一個變量存儲它們像這樣:

 new Cannon("down", tileX, tileY, 65); 

將這個對象永遠是符合垃圾收集?如果是,那麼它什麼時候纔會真正被處置?

==

對於我的炮班,我所有的實例添加到在創建靜態數組列表。這是我在使用垃圾收集第一次嘗試:

ArrayList<Cannon> cannonList = Cannon.getCannons(); 
    for (int i = 0; i < cannonList.size(); i++) { 
     Cannon c = (Cannon) cannonList.get(i); 
     c = null; 
    } 
    for (int i = 0; i < cannonList.size(); i++) { 
     cannonList.remove(i); 
    } 
    System.gc(); 

當我設置爲「C = NULL;」,它使原來炮爲「空」,從而使其符合垃圾收集,或者它爲對象創建一個新的引用c,然後將其設置爲null,使它對我無能爲力?

==

我的炮班不斷創建EnemyProjectile類的實例。 EnemyProjectiles類包含一個名爲「visible」的布爾型字段。當「可見」等於假時,處理我的EnemyProjectile類並使其有資格進行垃圾回收的正確方法是什麼?

+0

對象在不再有任何引用之後會被回收一段時間。基本方案是「標記和掃描」,其中一個程序首先「將」對象A的點「對象B」的整個「樹」移動到對象C ...處,「標記」每個對象到達。然後檢查所有對象,並將那些未標記爲可達的對象回收。 –

+1

_「它是否爲對象創建了一個新的引用c,然後將它設置爲null,使它對我而言什麼都不做?」_對它沒有任何幫助。從列表中刪除一個項目,並且(大概)不再提及它是什麼使它符合GC的條件。 – Radiodef

回答

2

使用Java的樂趣在於內存是在幕後管理的,所以與C或C++不同,您不必擔心解構或處理對象。當一個對象不再是「可用的」(由於超出範圍而無法從另一個活動對象訪問時定義),垃圾收集器悄然回收它佔用的空間。

在Java中,您無法控制何時垃圾收集對象,也不應該嘗試。

依賴於未使用對象的確定性垃圾回收的代碼總是很脆弱,難以在Java中維護。部分原因是因爲不同的JVM實現會在不同的時間進行垃圾收集。充其量,對JVM來說,它是做垃圾收集的建議,但不能保證什麼時候(或者甚至)會發生。

您可以做的最好的事情是設計您的程序,以便參考變量具有絕對最短的使用壽命。只要長壽命對象保留對短期對象的引用(監聽器是一個示例),或者當您創建自己「管理內存」的數據結構時(例如,自己的隊列或堆棧),您的代碼就有內存泄漏的風險實現)。

ArrayList<Cannon> cannonList = Cannon.getCannons(); 
for (int i = 0; i < cannonList.size(); i++) { 
    Cannon c = (Cannon) cannonList.get(i); 
    c = null; 
} 
for (int i = 0; i < cannonList.size(); i++) { 
    cannonList.remove(i); 
} 
System.gc(); 

在這個片段中,有幾個問題:

當您從Java集合API使用的數據結構,你應該使用的接口類型,而不是具體的類。這是慣例,但這樣做會使您的代碼更加靈活。代替...

ArrayList<Cannon> cannonList = Cannon.getCannons(); 

寫這個代替(適用於任何類實例實現List接口):

List<Cannon> cannonList = Cannon.getCannons(); 

如果可能的話,你應該使用增強的for-each與Java SE 5中引入循環是不易出錯。您的for循環應如下所示:

for (Cannon c : cannonList) { 
    c = null; // this for loop actually accomplishes no useful work since 
       // the reference is null'd as soon as it gets a reference to 
       // a Cannon object. The reference in your ArrayList is unaffected 
       // by this assignment 
} 

cannonList.clear(); // more concise than removing each element from the list. 

TL; DR:發生垃圾收集時發生。它是非確定性的。你永遠不能保證什麼時候,甚至是否會發生。設計你的Java程序,儘早讓你的對象有資格進行垃圾回收...然後不用擔心會發生什麼。