Flex記憶體洩露場景
轉:http://www.cnblogs.com/janyou/archive/2008/11/25/1340753.html
http://tech.ccidnet.com/art/3539/20100810/2148307_1.html
從目前情況看,Flex 3(AS3)存在嚴重的memoy leak(記憶體洩露)問題,這些問題中一部分可以合適的編碼方式來避免,還有一些問題目前只有等待Flex SDK更新了。
感覺Flex 的商業應用目前只能在初級階段。列舉一些產生memoy leak的情景。
(1)EventListeners
override protected function mouseDownHandler(e:Event):void
{
systemManager.addEventListener(“mouseUp”,mouseUpHandler);
}
解決辦法:
Ø 在dispose的時候移除監聽:
systemManager.removeEventListener(“mouseUp”, mouseUpHandler);
Ø 使用弱引用:
override protected function mouseDownHandler(e:Event):void
{
systemManager.addEventListener(“mouseUp”,mouseUpHandler, false, 0, true);
}
以下方式事件監聽不會導致記憶體洩露
Ø 弱引用
someObject.addEventListener(MouseClick.CLICK, handlerFunction,false, 0, true);
Ø 自身引用
this.addEventListener(MouseClick.CLICK, handlerFunction);
Ø
private var childObject:UIComponent = new UIComponent;
addChild(childObject);
childObject.addEventListener(MouseEvent.CLICK, clickHandler);
(2)static members
Class (或MXML)中有:
public static var _eventService : MyService=newMyService();
在dispose時,需要設定:
_eventService =null;
(3)module(未解決)
moduleLoader unloadModule後,ModuleInfo 並不會被GC.
Garbage Collectionin a MultiCore Modular Pipes Application
這篇文章介紹了一種GC策略,感覺對於ModuleInfo 的GC無效。(我打不開)
(4)CSSStyle
module 中如果使用了shell的CSS定義或是<mx:Style> (現在應該是<fx:Style>,這塊我沒有測試過)這樣的定義,那麼這個module將不能GC.
彈出的視窗應該是同樣的結果.
解決方法,使用動態CSS檔案
module init中
StyleManager.loadStyleDeclarations("css/myStyle.swf");
module dispose中
StyleManager.unloadStyleDeclarations("css/myStyle.swf");
(5)TextInput/Textarea(未解決)
如果module中有window使用了TextInput/Textarea控制元件,不點選沒有問題,只要點上去,那麼很遺憾了,module和所在窗體將不能被GC.這個BUG非常嚴重,目前還沒有解決方法。
memory leak whenusing TextInput and TextArea when click the keyboard
這裡面附加的解決方法無效。
通過profiler分析,應該和Focusmanager有關,只有一點選就不會釋放。
(6)CursorManager.setCursor
使用了
cursorID = CursorManager.setCursor(iconClosed);
dispose時要
CursorManager.removeCursor(cursorID);
(7)Bitmap
如果使用Bitmap,結束時需要呼叫其dispose方法,否則記憶體消耗巨大。
var bmp:Bitmap =new Bitmap();
if (bmp.bitmapData!=null) {
bmp.bitmapData.dispose();
}
(8)Image
包含了Image物件時,在removeChildren時會造成不能釋放(測試多次,結果不一,建議還是做如下處理)。
解決:
img.source = null;
this.removeChild(img);
img = null;
(9)Effect
當對元件應用效果Effect的時候,當本物件本刪除時需要把本物件和子物件上的Effect動畫停止掉,然後把Effect的target物件置null;如果不停止掉動畫直接把Effect置null將不能正常移除物件。(我自己測試發現,Effect的duration="0"也會導致記憶體洩露,設定大於0就不會了。)
(10)SWF洩露
要完全刪除一個SWF要呼叫它的unload()方法並且把物件置null;
(11)Timer
只要Timer一直在執行,就算程式不再引用,FLEX記憶體的記憶體回收機制也不會回收Timer及其相關類/變數的資源而且一直在執行。
解決方案:在dispose的時候:
if(timer)
{
timer.stop();
timer= null;
}
(12)聲音、視訊洩露
當不需要一個音樂或視訊是需要停止音樂,刪除物件,引用置null;
總結:Flex記憶體洩露解決方法:
Ø 在元件的REMOVED_FROM_STAGE事件中做垃圾處理操作(移除所有對外引用(不管是VO還是元件的都需要刪除),刪除監聽器,呼叫系統類的清除方法)
Ø 先remove再置null,確保被remove或者removeAll後的物件在外部的引用全部釋放乾淨;
Ø 利用Flex的效能優化工具Profile來對專案程序進行監控,可知道歷史建立過哪些物件,目前有哪些物件沒有被刪除,建立的數量,佔用的記憶體比例和用量,建立過程等資訊;