Flex內存泄露問題

文章二
FLEX內存優化技巧集合
類型:轉載
FLEX內存釋放優化原則
1. 被刪除對象在外部的所有引用一定要被刪除乾淨才能被系統當成垃圾回收處理掉;
2. 父對象內部的子對象被外部其他對象引用了,會導致此子對象不會被刪除,子對象不會被刪除又會導致了父對象不會被刪除;
3. 如果一個對象中引用了外部對象,當自己被刪除或者不需要使用此引用對象時,一定要記得把此對象的引用設置爲null;
4. 本對象刪除不了的原因不一定是自己被引用了,也有可能是自己的孩子被外部引用了,孩子刪不掉導致父親也刪不掉;
5. 除了引用需要刪除外,系統組件或者全局工具、管理類如果提供了卸載方法的就一定要調用刪除內部對象,否則有可能會造成內存泄露和性能損失;
6. 父對象立刻被刪除了不代表子對象就會被刪除或立刻被刪除,可能會在後期被系統自動刪除或第二次移除操作時被刪除;
7. 如果父對象remove了子對象後沒有清除對子對象的引用,子對象一樣是不能被刪除的,父對象也不能被刪除;
8. 註冊的事件如果沒有被移除不影響自定義的強行回收機制,但有可能會影響正常的回收機制,所以最好是做到註冊的事件監聽器都要記得移除乾淨。
9. 父對象被刪除了不代表其餘子對象都刪除了,找到一種狀態的泄露代碼不等於其他狀態就沒有泄露了,要各模塊各狀態逐個進行測試分析,直到測試任何狀態下都能刪除整個對象爲止。

內存泄露舉例:
1. 引用泄露:對子對象的引用,外部對本對象或子對象的引用都需要置null;
2. 系統類泄露:使用了系統類而忘記做刪除操作了,如BindingUtils.bindSetter(),ChangeWatcher.watch()函數時候完畢後需要調用ChangeWatcher.unwatch()函數來清除引用 ,否則使用此函數的對象將不會被刪除;
類似的還有MUSIC,VIDEO,IMAGE,TIMER,EVENT,BINDING等。
3. 效果泄露:當對組件應用效果Effect的時候,當本對象本刪除時需要把本對象和子對象上的Effect動畫停止掉,然後把Effect的target對象置null; 如果不停止掉動畫直接把 Effect置null將不能正常移除對象。
4. SWF泄露:要完全刪除一個SWF要調用它的unload()方法並且把對象置null;
5. 圖片泄露:當Image對象使用完畢後要把source置null;(爲測試);
6. 聲音、視頻泄露: 當不需要一個音樂或視頻是需要停止音樂,刪除對象,引用置null;
內存泄露解決方法:
1. 在組件的REMOVED_FROM_STAGE事件回掉中做垃圾處理操作(移除所有對外引用(不管是VO還是組件的都需要刪除),刪除監聽器,調用系統類的清除方法)
先remove再置null, 確保被remove或者removeAll後的對象在外部的引用全部釋放乾淨;
2. 利用Flex的性能優化工具Profile來對項目進程進行監控,可知道歷史創建過哪些對象,目前有哪些對象沒有被刪除,創建的數量,佔用的內存比例和用量,創建過程等信息;

總結:關鍵還是要做好清除工作,自己設置的引用自己要記得刪除,自己用過的系統類要記得做好回收處理工作。 以上問題解決的好的話不需要自定義強制回收器也有可能被系統正常的自動回收掉。

文章二

對於Flex性能我想是很多真正打算用它的人最關心的問題,也是我用了這麼久之後體會比較深刻的問題,
目前我做過的系統性能也是一個大問題,在這裏我總結了一些在技術上提高性能的方法。

1.避免容器的深層嵌套(因爲每個容器都會對其子容器進行計算和調整,一般建議HBox,VBox最好不要超過3層,但對於複雜系統這個很難避免)
2.對於容器和空間的位置和尺寸儘量採用絕對座標和硬編碼。(減少Flash Player深層次的嵌套計算)
3.合理恰當的使用Grid容器,對於能用普通容器如HBox,VBox實現的儘量不要採用Grid(Grid嵌套層次深)
4.避免使用重複、冗餘的容器嵌套,如:
 1) 在Panel,Application中添加一層VBox,Panel,Application本來就是繼承於VBox的,添加無謂的VBox只能降低你係統的性能。
 2) 對於自定義的容器減少重複多餘的父容器,比如:
  <mx:VBox backgroundColor=" #FFCCCC" borderStyle=" solid">
   <myComponent xmlns=" *" />
  </mx:VBox>
 你完全可以採用下面的寫法,對於myComponents可能它本身就是VBox
  <myComponent xmlns=" *" backgroundColor=" #FFCCCC" borderStyle="solid" />
5.延遲實例化導航類容器(Deferred Instantiation Navigator Containers)
   如ViewStack, Accordion, TabNavigator等,本身就提供了延遲實例化的功能,你只需要修改其creationPolicy='auto'即可,它將只實例化第一個要顯示的子控件,其餘的將在需要的時候實例化。
6.對於flex的效果(Effects)要做到儘量平滑(Smoothly),比如延長它的持續時間(duration),避免使用bmp格式的圖片作背景。
7.對於DataGrid的複雜ItemRenderer,儘量用Canvas而不是VBox or HBox,這個和Flex 1.5中是不同的。
8.如果DataGrid的ItemRenderer是ComboBox等,儘量用ItemEditor而不是ItemRenderer,只有當選中的cell纔會顯示其Renderer(避免一次性把所有的cell Renderer都畫出來)
9.記得隨時Remove 沒有用的Listener或採用弱引用,這個我在事件機制中提到過(URL...); null不用的變量和數組。
10.對於大批量的數據採用需要的時候去取或者分頁
11.提前聲明頻繁使用的變量,如:
var l:int=list.length;
var w:int = stage.stageWidth;
for(var i : int=0; i < l; i++){
 list[i].x = w -100;
}
12.這樣也能提高Flex的性能,可能很多人都會不屑,但至少對於Flex來講它能減少不必要的計算,改善性能,我想這個編程習慣問題要改還真是不容易,至少我寫了1年多直到最近才注意到這個問題。
另外和代碼組織有關的建議,如:
 1) 系統性的常量寫在一個常量類裏頭並用const關鍵字,一些ItemRenderer代碼儘量獨立成一個文件而不是直接到處都寫
 2) 不要在界面元素中引用一大串的parent.parent.parent...,一旦界面重新組織將給你帶來很大麻煩。如果你用Cairngorm框架,那麼就應該用ViewHelper,儘量的鬆耦合你的代碼。
13.修改 production-mode 屬性爲true,2.01在文件flex-webtier-config.xml中。它一般是產品發佈的時候要設置的,你可以理解爲c++的 Release和Debug版本之間的差異。
14.如果你用FDS,那麼儘量用Remote Object 而不是Http Service or Web Service,因爲前者的效率最高
15.對你的系統進行壓力測試,Adobe有一個測試工具,叫Flex Stress Testing Framework
(rul:http://labs.adobe.com/wiki/index.php/Flex_Stress_Testing_Framework).
它能提供對RPC中的RTMP, AMF,HTTP測試,一般的商業測試軟件不支持前兩者的測試,
該軟件完全免費,你可以到Adobe官網上下(URL: http://download.macromedia.com/pub/labs/flexstress/flex_stressfw_p2_060407.zip)

 

發佈了30 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章