前些天持續做了一些測試,以減深對AS3的┞菲握戰正在項目中洞課戲機能、效率劣化圓裏的一些處理,有許多測試實踐意義沒有年夜,皆不外是證實一些猜念是正確的,除此出有甚麼。
但前天停止的一戲誦測試中,有一些洞課戲開發中的內存佔趺,CPU佔趺圓裏又供意義,我籌算逐步寫幾篇會商性的文┞仿取各人同享。
因爲最遠正在做的是2D的等距視角遊轄爆局部接納的位圖處理,取3D無閉,以是存眷的也是那圓裏的問題,思索問題的動身面也是那些圓裏,因而存眷裏仍是比力狹小的。
1、先從那類2D遊戲中經常使用的對象類型的簡單測試去開端看AS3的蹬鰱是如何撐持
那隻能是管窺一斑,我也只能是據囪碰面推測,至於AS3蹬鰱到底如何完成,年夜可沒必要來弄的很分明,但測試的成果仍由以正在我們寫代碼時,做到胸有定見。
先去看測試函數代碼private function compareDisplayObject():void
{
len1 = System.totalMemory;
_txt.text = "測試前總內存鉅細爲:" + len1.toString();
var sprite:Sprite = new Sprite();
len2 = System.totalMemory;
_txt.appendText("\nnew Sprite後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nnew Sprite後增長的內存爲:" + (len2 - len1).toString());
var bmp:Bitmap = new Bitmap();
len1 = System.totalMemory;
_txt.appendText("\n\nnew Bitmap後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nnew Bitmap後增長的內存爲:" + (len1 - len2).toString());
var shape:Shape = new Shape();
len2 = System.totalMemory;
_txt.appendText("\n\nnew Shape後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nnew Shape後增長的內存爲:" + (len2 - len1).toString());
var rect:Rectangle = new Rectangle(0, 0, 200, 100);
len1 = System.totalMemory;
_txt.appendText("\n\nnew Rectangle,鉅細爲200*100後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nnew Rectangle,鉅細爲200*100後增長的內存爲:" + (len1 - len2).toString());
//正文失落上面冶,零丁測試將sprite、bmp、shape三個空對象加減到隱示列表。
sprite.graphics.drawRect(0, 0, 200,100);
len2 = System.totalMemory;
_txt.appendText("\n\nsprite畫造200*100的矩形後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nsprite畫造200*100的矩形後增長的內存爲:" + (len2 - len1).toString());
shape.graphics.drawRect(0,0,200,100)
len1 = System.totalMemory;
_txt.appendText("\n\nshape畫造200*100的矩形後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nshape畫造200*100的矩形後增長的內存爲:" + (len1 - len2).toString());
this.addChild(sprite);
len2 = System.totalMemory;
_txt.appendText("\n\n將sprite加減到舞臺後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nsprite加減到舞臺後增長的內存爲:" + (len2 - len1).toString());
this.addChild(bmp);
len1 = System.totalMemory;
_txt.appendText("\n\n將bmp加減到舞臺後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nbmp加減到舞臺後增長的內存爲:" + (len1 - len2).toString());
this.addChild(shape);
len2 = System.totalMemory;
_txt.appendText("\n\n將shape加減到舞臺後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nshape加減到舞臺後增長的內存爲:" + (len2 - len1).toString());
}
轉載註明盛世遊戲:http://www.shengshiyouxi.com
再去看輸出成果:
//------------------------------------------------>
測試前總內存鉅細爲:3162112
new Sprite後總內存鉅細爲:3162112
new Sprite後增長的內存爲:0
new Bitmap後總內存鉅細爲:3162112
new Bitmap後增長的內存爲:0
new Shape後總內存鉅細爲:3170304
new Shape後增長的內存爲:8192
new Rectangle,鉅細爲200*100後總內存鉅細爲:3182592
new Rectangle,鉅細爲200*100後增長的內存爲:12288
sprite畫造200*100的矩形後總內存鉅細爲:3190784
sprite畫造200*100的矩形後增長的內存爲:8192
shape畫造200*100的矩形後總內存鉅細爲:3198976
shape畫造200*100的矩形後增長的內存爲:8192
將sprite加減到舞臺後總內存鉅細爲:3207168
sprite加減到舞臺後增長的內存爲:8192
將bmp加減到舞臺後總內存鉅細爲:3211264
bmp加減到舞臺後增長的內存爲:4096
將shape加減到舞臺後總內存鉅細爲:3215360
shape加減到舞臺後增長的內存爲:4096
[color=ize:13px]//------------------------------------------------>
前天測試時,每次運轉FP,第一次根本上new Sprite,Bitmap,Shape後增長的內存皆沒有爲0,前兩者皆是4096,Shape是8192,但明天每次從頭運轉前裏兩個對象new 後內存增長皆是0。
運轉當前,屢次挪用那個函數,輸出的內容能夠看到內存每次反覆挪用時皆正在之前根底梢減,但那寂new 操做以後,內存的增長經常0,而Shape爲0的時分很少,大都是4096,偶然是8192。
我推測,那該當實了止時環境以爲new 出去的式昌,出有利用,而且援用計數也是0,以是被收受接管了,那從輸出內容的前面一些部門(對象被加減到隱示列表中),所隱示的內存增長一直年夜於0能夠看出去。
可是重複挪用那個函數時,將sprite式昌加減到隱示列表中,使得增長的內村卻經常正在4096戰8192之間變更,那讓我感應很是疑惑,念沒有到公道的解釋。
2、對sprite,bitmap,shape new 一批空對象,及將一批空對象加減到隱示列表的內存佔趺測試
那裏說的空對象沒有是指null的無值狀況,而是僅指new以後,沒有減任那邊理或賦值的狀況。
先去看測試代碼:private function compareMultiDisplayObject():void
{
//每類對象new的個數
var num:uint = 1000;
len1 = System.totalMemory;
_txt.text = "每匆汛建" + num.toString() + "個同類對象,測試前總內存鉅細爲:" + len1.toString();
var i:uint;
var sprite:Sprite;
var bmp:Bitmap;
var shape:Shape;
for (i = 0; i < num; i++)
{
sprite = new Sprite();
//恢復以下正文,讓new出去的對象有援用計數,躲免對象被以爲無利用而被收受接管
//arr.push(sprite);
}
len2 = System.totalMemory;
_txt.appendText("\nnew Sprite後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nnew Sprite後增長的內存爲:" + (len2 - len1).toString() + " || 均勻每一個增長:" + ((len2 - len1)/num).toString());
for (i = 0; i < num; i++)
{
bmp = new Bitmap();
//arr.push(bmp);
}
len1 = System.totalMemory;
_txt.appendText("\n\nnew Bitmap後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nnew Bitmap後增長的內存爲:" + (len1 - len2).toString() + " || 均勻每一個增長:" + ((len1 - len2)/num).toString());
for (i = 0; i < num; i++)
{
shape = new Shape();
//arr.push(shape);
}
len2 = System.totalMemory;
_txt.appendText("\n\nnew Shape後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nnew Shape後增長的內存爲:" + (len2 - len1).toString() + " || 均勻每一個增長:" + ((len2 - len1)/num).toString());
_txt.appendText("\n\n================以下爲創立並加減到隱示列表================");
for (i = 0; i < num; i++)
{
sprite = new Sprite();
this.addChild(sprite);
}
len1 = System.totalMemory;
_txt.appendText("\nnew Sprite後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nnew Sprite後增長的內存爲:" + (len1 - len2).toString() + " || 均勻每一個增長:" + ((len1 - len2)/num).toString());
for (i = 0; i < num; i++)
{
bmp = new Bitmap();
this.addChild(bmp);
}
len2 = System.totalMemory;
_txt.appendText("\n\nnew Bitmap後總內存鉅細爲:" + len2.toString());
_txt.appendText("\nnew Bitmap後增長的內存爲:" + (len2 - len1).toString() + " || 均勻每一個增長:" + ((len2 - len1)/num).toString());
for (i = 0; i < num; i++)
{
shape = new Shape();
this.addChild(shape);
}
len1 = System.totalMemory;
_txt.appendText("\n\nnew Shape後總內存鉅細爲:" + len1.toString());
_txt.appendText("\nnew Shape後增長的內存爲:" + (len1 - len2).toString() + " || 均勻每一個增長:" + ((len1 -len2)/num).toString());
}
轉載註明盛世遊戲:http://www.shengshiyouxi.com
前一部分測試是創建一批空對象,不作任何其他的操作,那麼這些對象的引用計數應該是0
後面一部分測試是創建一批空對象,並將創建的每個對象隨後添加到了顯示列表,那麼這批對象就同時有了引用計數,也即不對這些對象進行其他處理情況下的內存佔用。但對Bitmap對象還是略有不同,因爲並有爲其new 一個bitmapData對象實例,所以bitmap所佔內存這裏輸出的要比實際的低
下面來看測試輸出:
[color=ize:13px]//------------------------------------------------------------------------------->
每次創建1000個同類對象,測試前總內存大小爲:3158016
new Sprite後總內存大小爲:3665920
new Sprite後增加的內存爲:507904 || 平均每個增加:507.904
new Bitmap後總內存大小爲:3788800
new Bitmap後增加的內存爲:122880 || 平均每個增加:122.88
new Shape後總內存大小爲:4141056
new Shape後增加的內存爲:352256 || 平均每個增加:352.256
================以下爲創建並添加到顯示列表================
new Sprite後總內存大小爲:3760128
new Sprite後增加的內存爲:-380928 || 平均每個增加:-380.928
new Bitmap後總內存大小爲:4505600
new Bitmap後增加的內存爲:745472 || 平均每個增加:745.472
new Shape後總內存大小爲:4886528
new Shape後增加的內存爲:380928 || 平均每個增加:380.928
[color=ize:13px]//-------------------------------------------------------------------------------->
可以看到輸出中的這段:
[color=ize:13px]//------------------------------------------------------------->
new Sprite後總內存大小爲:3760128
new Sprite後增加的內存爲:-380928
[color=ize:13px]//------------------------------------------------------------->
內存增加是負值,如果看作是之前new 出的一批對象實例被回收了,重新創建一批Sprite實例,並添加到顯示列表中,比之前僅創建Sprite而不添加到顯示列表的內存“new Sprite後總內存大小爲:3665920”相比來說,還算是比較合理的。
所以這個負值也就不意外了。
另外,從這個測試函數內的源碼註釋部分,可以看到“arr.push(sprite);”這樣幾行,是當時測試new 出來的這一批對象,不添加到顯示列表,僅僅增加引用計數而進行的測試,可以與添加到顯示列表的內存開銷進行一下對比。
[color=ize:13px]//-------------------------------------------------------------------------------->
每次創建1000個同類對象,測試前總內存大小爲:3158016
new Sprite後總內存大小爲:3670016
new Sprite後增加的內存爲:512000 || 平均每個增加:512
new Bitmap後總內存大小爲:4444160
new Bitmap後增加的內存爲:774144 || 平均每個增加:774.144
new Shape後總內存大小爲:4796416
new Shape後增加的內存爲:352256 || 平均每個增加:352.256
================以下爲創建並添加到顯示列表================
new Sprite後總內存大小爲:5373952
new Sprite後增加的內存爲:577536 || 平均每個增加:577.536
new Bitmap後總內存大小爲:6160384
new Bitmap後增加的內存爲:786432 || 平均每個增加:786.432
new Shape後總內存大小爲:6500352
new Shape後增加的內存爲:339968 || 平均每個增加:339.968
[color=ize:13px]//---------------------------------------------------------------------------------->
看兩段輸出,很清楚,可以對比着看,不解釋。
三、對圖片加載和位圖常用操作的對比測試
先看測試函數,這個函數寫的還早,測試的還早,所以對輸出文字的處理跟前面兩個有點不一樣。private function compareBitmap():void
{
var loader:Loader = new Loader();
var path:String = "1.png";
var url:URLRequest = new URLRequest(path);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoader_Complete);
len2 = System.totalMemory;
_txt.text = "載入圖片前總內存大小爲:" + len2.toString();
loader.load(url);
}
private function imageLoader_Complete(e:Event):void
{
var text:String;
len1 = System.totalMemory;
text = _txt.text + "\n載入圖片後總內存大小爲:" + len1.toString();
text += "\n載入後增加的內存大小爲:" + (len1 - len2).toString();
var loader:Loader = e.target.loader as Loader;
var bmp:Bitmap = loader.content as Bitmap;
text += "\n\nloader的總字節數爲:" + loader.contentLoaderInfo.bytesTotal.toString();
text += "\nBitmap的總字節數爲:" + bmp.loaderInfo.bytesTotal.toString();
text += "\n當前總內存大小爲:" + System.totalMemory.toString();
var bmpData:BitmapData = bmp.bitmapData;
len2 = System.totalMemory;
text += "\n\nBitmapData賦值後的總內存大小爲:" + len2.toString();
bmpData.copyPixels(bmp.bitmapData, new Rectangle(0,0,bmp.width,bmp.height), new Point(0, 0));
len1 = System.totalMemory;
text += "\ncopyPixels位圖對象的bitmapData後的總內存大小爲:" + len1.toString();
bmpData.draw(bmp);
len2 = System.totalMemory;
text += "\nbitmapData.draw()位圖對象後的總內存大小爲:" + len2.toString();
var bmp1:Bitmap = new Bitmap();
text += "\nnew一個Bitmap空對象bmp1後的總內存大小爲:" + System.totalMemory.toString();
bmp1.bitmapData = bmpData;
text += "\n對bmp1.bitmapData賦值後的總內存大小爲:" + System.totalMemory.toString();
var bmp2:Bitmap = new Bitmap(bmpData);
text += "\n使用得到的bmpData對象生成bmp2後的總內存大小爲:" + System.totalMemory.toString();
this.addChild(bmp1);
text += "\n將bmp1添加到顯示列表後的總內存大小爲:" + System.totalMemory.toString();
this.addChild(bmp2);
text += "\n將bmp2添加到顯示列表後的總內存大小爲:" + System.totalMemory.toString();
bmp1.x = 300;
bmp1.y = 0;
bmp2.x = 400;
bmp2.y = bmp2.height + 10;
text += "\n\n圖片寬度=" + bmp.width.toString() + ",高度=" + bmp.height.toString();
text += "\n按PNG圖片像素內存佔用<ARGB*width*height>\n來計算,則純像素佔內存= 4 * " + bmp.width.toString() + " * " + bmp.height.toString() + " =" + (4 * bmp.width * bmp.height).toString();;
len2 = System.totalMemory;
text += "\n\n當前總內存大小爲:" + len2;
bmpData = bmp.bitmapData.clone();
len1 = System.totalMemory;
text += "\n克隆位圖對象的bitmapData後的總內存大小爲:" + len1.toString();
text += "\n克隆後增加的內存大小爲:" + (len1 - len2).toString();
var num:uint = 1000;
var j:uint;
var tempBMP:Bitmap;
var rect:Rectangle = new Rectangle(0, 0, bmp.width, bmp.height);
var vertex:Point = new Point(0, 0);
var dt:int = getTimer();
len2 = System.totalMemory;
text += "\n\nnum=" + num.toString() + " || 當前總內存大小爲:" + len2;
for (j = 0; j < num; j++)
{
tempBMP = new Bitmap();
//tempBMP.bitmapData = bmp.bitmapData;
tempBMP.bitmapData = new BitmapData(bmp.width, bmp.height);
tempBMP.bitmapData.copyPixels(bmp.bitmapData, rect, vertex);
this.addChild(tempBMP);
tempBMP.x = j + 300;
tempBMP.y = j;
}
len1 = System.totalMemory;
dt = getTimer() - dt;
text += "\n生成num個位圖並添加到顯示列表中後的總內存大小爲:" + len1.toString();
text += "\n生成num個位圖並添加到顯示列表中後增加的內存大小爲:" + (len1 - len2).toString();
text += "\n花費時間:" + dt.toString() + "毫秒 || 平均操作每個對象需時:" + (dt / num).toString();
_txt.text = text;
}
轉載註明盛世遊戲:http://www.shengshiyouxi.com
對上面這段代碼裏面的for循環裏面部分,以循環1000次爲例,我進行三種測試。for (j = 0; j < num; j++)
{
tempBMP = new Bitmap(bmp.bitmapData);
this.addChild(tempBMP);
tempBMP.x = j + 300;
tempBMP.y = j;
}
上面這種測試由載入的bitmapData直接生成要使用的位圖,以方便添加到顯示列表中使用。
上面這種測試輸出是:
[color=ize:13px]//------------------------------------------------------------------------->
載入圖片前總內存大小爲:3174400
載入圖片後總內存大小爲:3526656
載入後增加的內存大小爲:352256
loader的總字節數爲:61831
Bitmap的總字節數爲:61831
當前總內存大小爲:3526656
BitmapData賦值後的總內存大小爲:3526656
copyPixels位圖對象的bitmapData後的總內存大小爲:3526656bitmapData.draw()位圖對象後的總內存大小爲:3526656
new一個Bitmap空對象bmp1後的總內存大小爲:3526656
對bmp1.bitmapData賦值後的總內存大小爲:3526656
使用得到的bmpData對象生成bmp2後的總內存大小爲:3526656
將bmp1添加到顯示列表後的總內存大小爲:3526656
將bmp2添加到顯示列表後的總內存大小爲:3526656
圖片寬度=256,高度=255
按PNG圖片像素內存佔用<ARGB*width*height>
來計算,則純像素佔內存= 4 * 256 * 255 =261120
當前總內存大小爲:3526656
克隆位圖對象的bitmapData後的總內存大小爲:3788800
克隆後增加的內存大小爲:262144
num=1000 || 當前總內存大小爲:3788800
生成num個位圖並添加到顯示列表中後的總內存大小爲:4452352
生成num個位圖並添加到顯示列表中後增加的內存大小爲:663552
花費時間:103毫秒 || 平均操作每個對象需時:0.103
[color=ize:13px]//----------------------------------------------------------------------------->
再來看將for中代碼修改爲new出一個空bitmap之後,對其bitmapData賦值的做法,有沒有不同。for (j = 0; j < num; j++)
{
tempBMP = new Bitmap();
tempBMP.bitmapData = bmp.bitmapData;
this.addChild(tempBMP);
tempBMP.x = j + 300;
tempBMP.y = j;
}
請看輸出:
[color=ize:13px]//-------------------------------------------------------------------------------->
載入圖片前總內存大小爲:3174400
載入圖片後總內存大小爲:3526656
載入後增加的內存大小爲:352256
loader的總字節數爲:61831
Bitmap的總字節數爲:61831
當前總內存大小爲:3526656
BitmapData賦值後的總內存大小爲:3526656
copyPixels位圖對象的bitmapData後的總內存大小爲:3526656
bitmapData.draw()位圖對象後的總內存大小爲:3526656
new一個Bitmap空對象bmp1後的總內存大小爲:3526656
對bmp1.bitmapData賦值後的總內存大小爲:3526656
使用得到的bmpData對象生成bmp2後的總內存大小爲:3526656
將bmp1添加到顯示列表後的總內存大小爲:3526656
將bmp2添加到顯示列表後的總內存大小爲:3526656
圖片寬度=256,高度=255
按PNG圖片像素內存佔用<ARGB*width*height>
來計算,則純像素佔內存= 4 * 256 * 255 =261120
當前總內存大小爲:3526656
克隆位圖對象的bitmapData後的總內存大小爲:3788800
克隆後增加的內存大小爲:262144
num=1000 || 當前總內存大小爲:3788800
生成num個位圖並添加到顯示列表中後的總內存大小爲:4456448
生成num個位圖並添加到顯示列表中後增加的內存大小爲:667648
花費時間:17毫秒 || 平均操作每個對象需時:0.017
[color=ize:13px]//------------------------------------------------------------------------------->
我之前試了很多次,這種處理,會比上面一種生成時直接以bitmapData來生成bitmap花費的時間要長一點,內存也多一點,不知這次如何,我修改代碼後運行直接把輸出複製過來了,也沒細看。
提交以後看到前一次的輸出,時間好久,喜歡動手的下載下面的RAR文件自己多測試幾次吧,有時候測試效果不穩定,這很無奈。
下面來看另一種情況,new 出來bitmap後再new 出來一個bitmapData不填充值的對象,然後再利用其CopyPixels函數來處理,在看代碼和效果前,一定明白這樣相當於這個bitmap採用了一張新的位圖,而CopyPixels函數,只是把另外一張位圖中的數據重新指向過來。看完修改的代碼和輸出後,下面再細說。for (j = 0; j < num; j++)
{
tempBMP = new Bitmap();
tempBMP.bitmapData = new BitmapData(bmp.width, bmp.height);
tempBMP.bitmapData.copyPixels(bmp.bitmapData, rect, vertex);
this.addChild(tempBMP);
tempBMP.x = j + 300;
tempBMP.y = j;
}
請看輸出:
[color=ize:13px]//------------------------------------------------------------------------------------>
載入圖片前總內存大小爲:3174400
載入圖片後總內存大小爲:3530752
載入後增加的內存大小爲:356352
loader的總字節數爲:61831
Bitmap的總字節數爲:61831
當前總內存大小爲:3530752
BitmapData賦值後的總內存大小爲:3530752
copyPixels位圖對象的bitmapData後的總內存大小爲:3530752
bitmapData.draw()位圖對象後的總內存大小爲:3530752
new一個Bitmap空對象bmp1後的總內存大小爲:3530752
對bmp1.bitmapData賦值後的總內存大小爲:3530752
使用得到的bmpData對象生成bmp2後的總內存大小爲:3530752
將bmp1添加到顯示列表後的總內存大小爲:3530752
將bmp2添加到顯示列表後的總內存大小爲:3530752
圖片寬度=256,高度=255
按PNG圖片像素內存佔用<ARGB*width*height>
來計算,則純像素佔內存= 4 * 256 * 255 =261120
當前總內存大小爲:3530752
克隆位圖對象的bitmapData後的總內存大小爲:3792896
克隆後增加的內存大小爲:262144
num=1000 || 當前總內存大小爲:3792896
生成num個位圖並添加到顯示列表中後的總內存大小爲:266907648
生成num個位圖並添加到顯示列表中後增加的內存大小爲:263114752
花費時間:1236毫秒 || 平均操作每個對象需時:1.236
[color=ize:13px]//------------------------------------------------------------------------------------>
看看上面輸出結果的最後兩行,是不是很讓人驚奇,好大的內存增加,以及好長的時間花費,CPU佔用還好,我第一次測試時,num=10000,最後超過默認的15秒不響應限制,也沒有出來結果,但CPU佔用一直穩定在25%(僅FP,還是在debug模式下),而且操作系統提示虛擬內存不足。
從最後一個測試可以看出,我們要儘量少用new BitmapData()這個函數,如果使用了這個函數,基本相當於引入了一張新位圖圖片。
[color=ize:16px]四、結論和我的猜測
結論將是由以上測試總結出的可驗證的判斷,但我的猜測就不行了,將僅僅是這些結論往前回溯性的猜測,所以可能被我蒙中了,也可能根本就是瞎猜,看到的各位,可以算做拋磚引玉,由此討論,但不要就此擡扛。
1、通過前面對CopyPixels函數的測試,可以看到,這個函數是極節省內存的。與直接使用一個位圖的bitmapData數據生成一個新的bitmap基本沒有差別。而且速度也很不錯。
//--------------------------------------------------------------->
num=1000 || 當前總內存大小爲:3788800
生成num個位圖並添加到顯示列表中後的總內存大小爲:4452352
生成num個位圖並添加到顯示列表中後增加的內存大小爲:663552
花費時間:103毫秒 || 平均操作每個對象需時:0.103
[color=ize:16px]//--------------------------------------------------------------->
這段輸出是對循環1000次,先給bitmapData賦值,再調用CopyPixels的測試輸出,看內存的增加與,跟去掉CopyPixels操作之後基本沒有差別。
2、在使用位圖資源時,儘可能的少用new BitmapData來生成位圖,因爲這相當於載入了一張新位圖。
3、位圖資源無論文件本身如何壓縮,如何小,但載入內存後,其佔用的內存空間,基本可按<ARGB*width*height>來計算,當然實際結果會比這個數值略大,這可以從測試中的Clon()函數的調用內存增加看出。
4、由結論3,可以推導出一個遊戲的flash客戶端中,究竟可以引入多少位圖資源,按照webgame的內存佔用率一半,CPU等計算資源30%的原則來算佔用的最大內存,單獨一個web game的內存佔用量上限可考慮300MB~600MB,以輕量級的web game 上限內存300MB來算,那就是1024*1024分辯率的圖片JPG之類無alpha通道的圖片100張,PNG格式有alpha通道的圖片75張,無論是矢量存儲載入後轉位圖,還是直接就是位圖。而這個位圖資源的上限公式,可以作爲一個遊戲項目的主策劃用來限制隨意策劃的一個測量標尺。
//---------------------------------------------------------------------------------------------------------------------->
以下是我猜測性的推論,請審慎視之
1、從內存增量上來看,使用已載入的位圖資源數據來new 出一個新的位圖,應該僅是生成了一個位圖對象,而實際的位圖數據還是指向原始的位圖資源。
2、人爲的在代碼中調用垃圾回收機制,既沒必要,也不需要,反而徒增系統資源的浪費。
3、普通對象的引用計數清除很重要,這關係到這些對象佔用內存的回收。
4、位圖類對象的位圖數據,調用銷燬函數很有必要,在不使用某個位圖資源時,將某個位圖資源手動銷燬,垃圾回收並不起作用。
5、bitmapData相比普通的類對象,要特別一點,特別之處有二,一是該對象引用指向的對象實際數據區,需要手動銷燬才能退出佔用的內存;另一是對該對象引用指向的實際數據,在進行數據修改,以讓其顯示的位圖有不同的顯示效果時,該修改並不是直接在實際的原始數據上進行修改的。
6、從bitmapData的特別之處,可以看到,流佈於一些AS3效率優化文章內的慎用濾鏡等之類的看法,應該也是這個問題的延伸。