1. 程式人生 > >Flex記憶體洩露場景

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來對專案程序進行監控,可知道歷史建立過哪些物件,目前有哪些物件沒有被刪除,建立的數量,佔用的記憶體比例和用量,建立過程等資訊;