2012-08-13 29 views
2

如果我有一個類刪除自己,它的內部方法應該停止執行嗎?我有一個B類告訴類A從A的ArrayList中刪除B.我相當肯定B只存在於A的ArrayList中,所以當我刪除它時,它應該被刪除,對吧? (注意:我已經包含了一個Serializable實現,以防萬一虛擬機如何處理我的類,但是我沒有在這裏寫入read-和writeObject方法,我懷疑它與這個方法有什麼關係。這個問題雖然)。垃圾收集的頻率如何?我不認爲我的對象被刪除

public class A implements Serializable, B_Listener { 
    ArrayList<B> bArray; 

    public A() { 
     bArray = new ArrayList<SomeObject>(); 
     bArray.add(new B(bArray.size(), this)); 
    } 

    @Override 
    public void deleteAtIndex(int index) { 
     bArray.remove(index); 
    } 
} 

public class B implements Serializable { 
    B_Listener listener; 
    int index; 

    public B(B_Listener listener, int index) { 
     this.listener = listener; 
     this.index = index; 
    } 

    //This is called at some point in a B's lifetime. 
    private void selfDestruct() { 
     listener.deleteAtIndex(index); 
     Log.w("B.class", "Should this not output? It does."); 
    } 
} 

public interface B_Listener { 
    public void deleteAtIndex(int index); 
} 

所以,當我不相信它應該在Log.w消息執行。因此,我害怕我正在創建java的內存泄漏。我查看並查看了我的代碼,試圖找到B可能被指針佔據的位置,但除了我的意圖之外,我什麼都沒有提出。

因此,我問是否垃圾收集在不同的時間比在我的結尾刪除B.如果是這種情況,那麼現在是否可以安全地說我實際上並不持有我不打算持有的物品?因爲我在Android上開發:我的B類保存了View對象,它們包含一個或多個視圖對象,指向B作爲聽衆。當我刪除視圖時,視圖管理器或任何Android應該不再指向視圖,我相信,並且當我刪除B時,它的所有內部視圖也應該被刪除,這意味着它們不能再由它們自己的監聽器保存B存在指針。我只是在談論這個問題,看看我的理解是否正確。

+0

誰在調用'B.selfDestruct()'? – 2012-08-13 00:35:00

+0

你問爲什麼第二行「selfDestruct」仍然在第一行之後執行? (爲什麼不應該這樣?)FWIW垃圾收集應該對應用程序完全不可見,並且不會干擾其行爲。它所做的只是確保有足夠的內存可用。不要試圖與之交互。 – Thilo 2012-08-13 00:35:24

+0

B有幾個狀態,所以如果B發現自己處於一個無用的狀態,它會調用selfDestruct()。在我的實際代碼中,沒有selfDestruct方法,而是狀態處理程序(在B中)我構建的只是執行行listener.deleteAtIndex(index)。 我不想與垃圾收集進行交互。我試圖理解它。我沒有被教過Java,我被教過C++。 – Cobryis 2012-08-13 00:39:16

回答

7

當然不是。

如果方法return s,引發異常或線程被中止,方法將只會「停止執行」。

垃圾收集的關鍵在於它對你而言是不可見的。除非有特殊的技巧(如WeakReferences或檢查空閒內存),否則不可能判斷一個對象是否被垃圾收集,如果可以檢查它是否存在,那意味着你有一個對它的引用,所以它不能被收集。

+2

特別是,當它的一個方法仍在運行時,「this」無法收集垃圾。至少,調用當前方法的對象仍然具有對該對象的引用(在方法調用完成並且堆棧解開後可能會消失,但不會在此之前)。 – Thilo 2012-08-13 00:39:35

+0

謝謝你們!這是我需要聽到的。我認爲垃圾收集是瞬間的。不幸的是,我不能upvote你的迴應,因爲我是新的:( – Cobryis 2012-08-13 00:41:42

+0

@Cobryis通常不會除了在引用計數實現.. – 2012-08-13 00:42:57

1
  1. 通常會有出現兩種GC的:未成年人(每秒左右)和重大(每隔一小時左右,但如果你給你的虛擬內存不足可能還有一個星期)。

  2. 對象以異步方式釋放(這樣做大大有效,它有助於保持內存不被碎片化)。它們不會在毫秒內被刪除,因此無法訪問。

  3. 垃圾收集纔有意義,如果沒有積極線程能夠訪問的對象,而不是當沒有對象持有對它的引用。在你的代碼中,只要selfDestruct運行,線程就擁有一個隱含的「this」引用。這導致該對象確實被一個線程引用 - 並且不受GC限制。

+0

謝謝,這加強了上面的答案,並進一步加強了我的瞭解GC。 – Cobryis 2012-08-13 00:49:33

相關問題