2012-01-23 54 views
2

遇到一些麻煩對象刪除後,我跑一個簡單的測試:對象()調用

  1. 創建一個簡單的類與弱引用偵聽Event.ENTER_FRAME。
  2. 增加了一個trace("I Exist!")呼叫到收聽的功能。
  3. 在文檔類中使用一個引用實例化單個實例。

按預期工作 - SWF文件除了打印「我存在!每一幀到控制檯。 (在調試模式,當然)

我沒有未來沒有工作,如我所料:
我設置被設置爲null上的鼠標事件對象的唯一參考,但該事件的消息所述對象的監聽者在鼠標事件被觸發並且參考設置爲null之後仍然出現在控制檯中 - 意味着對象仍然存在!

文檔類中調用System.gc()立即從印刷的進一步消息停止了事件偵聽器,看似刪除的項目。

據我所知,打電話System.gc()不鼓勵,但從這個簡單的測試看來,垃圾收集器是一個大的FAIL。
我在嘗試處理這個對象時做了些什麼錯誤,或者我應該每次只想調用System.gc()來擺脫一個對象..?

編輯:調用System.gc()與非弱聽者也導致看似從內存中刪除的對象

+1

的System.gc()只適用於Flash Player調試 - 你將不能夠在生產中使用它。 – weltraumpirat

回答

3

垃圾收集是在現代的虛擬機(Java,Flash播放器,.NET幾乎總是延遲(?)等)。你可以閱讀http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html瞭解更多信息。

特別是:

在Flash Player 9,垃圾收集器的操作被推遲。這是一個非常重要的理解。刪除所有活動引用時,您的對象不會立即被刪除。相反,它們將在未來的某個不確定時間被刪除(從開發者的角度來看)。垃圾回收器使用一組啓發式方法來查看RAM分配和內存堆棧的大小,以確定何時運行。作爲一名開發人員,您必須接受這樣一個事實,即您無法知道您的非活動對象何時,甚至是否會被釋放。你還必須意識到,非活動對象將繼續無限地執行,直到垃圾收集器釋放它們,所以你的代碼將繼續運行(enterFrame事件將繼續),聲音將繼續播放,加載將繼續發生,其他事件將繼續觸發,等等。

1

實際上,這是Flash垃圾收集系統的預期行爲。每次調用System.gc()或創建新對象時都會運行垃圾收集例程(new關鍵字)。您應該允許GC自然清理對象,反正System.gc()僅適用於調試播放器,並且對發佈版本不做任何處理。

如果您想讓偵聽器啓動,最好使用removeEventListener手動刪除偵聽器。但是,如果您不關心直到下一個收集階段的現有功能,則可以依靠弱聽者。希望這可以幫助。

0

Garbage collection is only triggered by allocation in Flash Player將一個對象設置爲null不會導致垃圾收集器被調用。

將對象設置爲null僅刪除對該對象的特定引用。事實上,你的聽衆仍然有一個對象的引用,在你的情況下它是一個弱引用,所以當GC運行時,對象被收集,但直到那時它仍然在內存中 - 調度和接收任何事件,你設置它處理。

處理這個問題的正確方法是顯式刪除不再需要的事件偵聽器,然後讓GC在其準備好時做好準備工作。通常我通過在我的課程中添加一個destroy()方法來處理這個問題,這樣我們就可以在他們離開之前清理他們自己的垃圾。

-1

您確定刪除了所有對象的引用嗎?即,您是否刪除了鼠標事件偵聽器,如果您將該對象添加到舞臺上,您是否刪除了該鼠標?

確定所有參考已被刪除後,返回null對象

object = null;

那麼重要的調用System.gc()兩次

垃圾收集CAL有兩個階段,標記和清除。每次調用System.gc()只執行一個階段。

這是一款出色的文章和工具,可讓您跟蹤應用中的對象,以便隨時瞭解哪些對象仍然具有對它們的引用。

http://divillysausages.com/blog/tracking_memory_leaks_in_as3

+0

System.gc()不適用於Flash的發行版。它只是用來做測試。如果你以正確的方式開發事物,程序員就不應該在乎GC的運行時間。實際上,我很喜歡GC,因爲我先前將所有對象都實例化並在應用程序中重複使用它們。不浪費! :) –