AVM2理論上是自帶垃圾回收機的,但是具體何時進行垃圾回收,理論上非人爲所能控制,而我們若要強制啓用垃圾回收機,則需要用一些非正規手段,比如如下會提到的手段。
所謂強制執行垃圾回收機,是指通過故意使swf在運行時出錯,然後throw出錯誤,而同時通過catch error來繼續運行swf文件。而垃圾回收機則會在swf拋出錯誤的時候,被強制執行一次,以清除內存中無效的數據佔用,減少資源的消耗。
try{
new LocalConnection().connect("MoonSpirit");
new LocalConnection().connect("MoonSpirit");
}catch(error : Error){}運行上述代碼,可強制執行一次垃圾回收機。具體測試:
分別用initNoBitmapDataView()和initBitmapDataView()進行10k個舉行元素創建
測試結果:
1.1不使用BitmapData 內存佔用 40M
2.1使用BitmapData 依舊內存佔用 40M!
原因分析: 雖然_sqrList被設爲null,但是原先被_sqrList所引用的1w個sprite數據依舊在內存中存在,雖然AMV2自帶垃圾回收機,但是何時進行垃圾回收是不確定的。而要強制執行垃圾回收機,則要用上文提到的hack手段
2.2使用BitmapData + 垃圾回收hack 內存佔用 12M
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.net.LocalConnection;
public class MoonSpirit extends Sprite
{
private const SQR_AMOUNT : int = 10000; //方塊數量
private var _container_sp : Sprite; //容器sprite
private var _sqrList : Array; //所有方塊的引用
public function MoonSpirit()
{
init();
}
private function init() : void{
_container_sp = new Sprite();
addChild(_container_sp);
// initNoBitmapDataView( );
initBitmapDataView();
}
//初始化 通過通常手段 顯示
private function initNoBitmapDataView() : void {
layoutTenThousandSqr();
}
//初始化 通過BitmapData快照 顯示
private function initBitmapDataView() : void {
layoutTenThousandSqr();
var myBitmapDataObject : BitmapData = new BitmapData(150, 150, false, 0xFF0000);
var myImage:Bitmap = new Bitmap(myBitmapDataObject);
addChild(myImage);
unLayoutTenThousandSqr();
_sqrList = null;
doClearance();
}
private function layoutTenThousandSqr() : void {
_sqrList = new Array();
for(var i : int = 0; i < SQR_AMOUNT; i++){
_sqrList.push(new Sprite());
_sqrList[i].graphics.beginFill(0xff0000);
_sqrList[i].graphics.drawRect(0,0,100,100);
_sqrList[i].graphics.endFill();
_container_sp.addChild(_sqrList[i]);
}
}
//不顯示
private function unLayoutTenThousandSqr() : void {
for(var i : int = 0; i < SQR_AMOUNT; i++){
_container_sp.removeChild(_sqrList[i]);
delete _sqrList[i];
}
}
//精髓,垃圾回收機強制調用
private function doClearance( ) : void {
trace("clear");
try{
new LocalConnection().connect("foo");
new LocalConnection().connect("foo");
}catch(error : Error){
}
}
}
}