簡體   English   中英

顯示Flex對象引用

[英]Displaying Flex Object References

我的Flex應用程序中存在一些內存泄漏問題,我的問題的簡短版本是:有沒有辦法(在AcitonScript 3中)查找給定對象的所有實時引用?

我所擁有的是一些視圖,每個視圖背后都有演示模型(使用Swiz)。 感興趣的視圖是TabNavigator的子視圖,因此當我關閉選項卡時,視圖將從舞台中刪除。 從階段中刪除視圖時,Swiz會將視圖中的模型引用設置為null,就像它應該的那樣。 我也從視圖中刪除了AllChildren()。

但是,在分析應用程序時,當我執行此操作並運行GC時,視圖和表示模型都不會被釋放(盡管兩者都將它們的引用設置為null)。 視圖使用的一個模型對象(雖然不是演示者)已被釋放,因此它並未完全被破壞。

我今天剛剛開始進行剖析(堅信不會過早地進行優化),所以我想有某種參考浮動在某處,但我看不到哪里,以及什么是超級有用的將是調試的能力並查看引用目標對象的對象列表。 這一切都是可能的,如果不是原生的話,是否有一些輕量級的方法將其編碼到未來的應用程序中以進行調試?

干杯。

假設您使用的是Flex Builder,則可以嘗試使用Profiler。 根據我的經驗,它對於分析性能並不是那么好,但它對於發現內存泄漏有很大幫助。

它不是最直觀的工具,需要一段時間才能適應它(我的意思是,它實際上變得有用)。 但是,在我看來,投入一些時間來至少學習基礎知識是值得的。 只看到玩家在全球范圍內使用了多少內存(System.totalMemory給你的內容,一個非常粗略,不精確且經常誤導的指標)並且實際跟蹤每個對象創建了多少個實例,仍有多少仍然存在巨大差異活着,他們分配在哪里(所以你可以找到代碼中的潛在泄漏並實際修復它而不是依賴於黑魔法)。

我不知道有什么關於FB探測器的好教程,但也許這對你有所幫助。

首先,啟動探查器。 取消選中性能分析並檢查其他所有內容(啟用內存分析,監視實時內存數據並生成對象分配堆棧跟蹤)。

當探查器啟動時,您將看到按類分組的應用程序對象的統計信息。 此時,您可能想要調整過濾器。 你會看到很多數據,很容易被淹沒。 現在,如果可能的話,忽略flash和flex中的所有東西,並專注於你認為應該收集的一些對象。

最重要的數字是“累積實例”和“實例”。 第一個是到目前為止創建的實例總數; 第二,所述實例的數量仍然存在。 因此,一個好的起點是讓您的應用程序進入您懷疑泄漏被創建的視圖所在的狀態。 您應該看到“累積實例”和“實例”1。

現在,做任何你需要做的事情來達到應該清理這個視圖的點(導航到應用程序的其他部分等)並運行GC(在探查器UI中有一個按鈕)。 關鍵的一點是,您將根據您的期望檢查應用行為 - 如果這是有道理的。 根據定義,在收集環境中自動發現泄漏幾乎是不可能的; 否則,就不會有泄漏。 所以,記住這一點:你測試你的期望; 你是那個知道物體生命周期的人,可以說,“此時應該收集這個物體;如果不是,就會出現問題”。

現在,如果你的視圖的“實例”計數下降到0,那里就沒有泄漏。 如果您認為應用程序泄漏,請嘗試查找可能未正確處理的其他對象。 如果計數保持為1,則表示您的視圖已泄露。 現在,你必須找到原因和地點。

此時,您應該拍攝“內存快照”(Force GC按鈕旁邊的按鈕)。 打開快照,在網格中找到對象並雙擊它。 這將為您提供所有引用此對象的對象的列表。 它實際上是一棵樹,可能每個項目都會包含許多反向引用等等。 這些是阻止收集視圖的對象。 在右側面板中,您還將獲得分配跟蹤。 這將顯示如何創建所選對象(非常類似於堆棧跟蹤)。

你可能會看到那里有很多物體。 但最好的辦法是專注於那些生命周期比你正在檢查的對象(你的觀點)更長的人。 我的意思是,尋找舞台,父母觀點等; 視圖所依賴的對象,而不是依賴於視圖的對象,如果這有意義的話。 如果您的視圖有一個按鈕並且您添加了一個監聽器,那么您的按鈕將具有您的視圖的參考。 在大多數情況下,這不是問題,因為按鈕取決於視圖,一旦收集視圖,按鈕也是如此。 因此,我們的想法是,由於有很多物體,你應該保持專注,否則你將無處可去。 這種方法頗具啟發性,但根據我的經驗,它可行。

一旦找到泄漏源,請返回源代碼,相應地更改代碼(這可能不僅需要更改代碼,還需要重構一下)。 然后重復此過程並檢查您的更改是否已產生預期效果。 這可能需要一段時間,具體取決於您的應用程序的大小或復雜程度以及您對它的了解程度。 但如果你一步一步地找到並解決一個問題,你最終會擺脫泄漏。 或者至少是最糟糕的,更明顯的。 所以,雖然有點單調乏味,但它會得到回報(而且作為一個好的方面,你最終會明白在大多數情況下浪費時間來為地球上的每一個事件處理程序使用弱refs,將每個事件都歸零單變量等等;這是一種啟發性的體驗;)。

希望這可以幫助。

Flash GC使用引用計數和標記和掃描的混合,因此它確實檢測循環引用。 看來你在對象圖中有另一個引用。 最常見的原因是,您想要處理的對象仍然具有在未處置的對象上注冊的事件處理程序。 您可以嘗試確保處理程序始終使用弱引用進行注冊。 如果可能,您還可以覆蓋所有(基類)類中的addEventListener和removeEventListener,以查看哪些偵聽器已注冊,以及是否有可能無法刪除某些偵聽器。

此外,您可以為對象編寫析構函數,為ui組件清除圖形並刪除所有子對象,對於所有對象,刪除對所有屬性的引用。 這樣,只有你的對象被保存在RAM中,這不需要太多內存(20 B左右的小占用空間,每個變量加4 B(數字為8))。

格爾茨
back2dos

也是尋找內存泄漏的有用啟發式方法: http//www.tikalk.com/flex/solving-memory-leaks-using-flash-builder-4-profiler

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM