[英]AS3 Memory Management reverse engineering
有人知道AS3如何真正處理垃圾回收嗎? 我正在開發的游戲中釋放內存有很多問題。
做了一個小演示:
public class MemoryTesting extends Sprite
{
static protected var list:Array = null;
public function onKeyDown(event:KeyboardEvent):void {
if( event.keyCode == 65 ){ //A key - adds memory
if( list == null ){
list = [];
for( var index:int = 0; index < 10000000; ++index ){
list.push(new Matrix3D());
}
}
}
else{ //Any other key removes memory.
if( list ){
var size:int = list.length;
for( var index:int = 0; index < size; ++index ){
list.pop();
}
list.length = 0;
list = null;
}
System.gc();
}
}
}
在Windows 7中運行Flash Player Debugger獨立的11.4r402。在沒有按下任何鍵的情況下,看着任務管理器,調試器處於11,000 K的空閑狀態。
按下(添加10Mil Matrix3D類)會將其增加到962,000K。
按下另一個鍵(刪除對矩陣的引用並使數組為空)取決於我按下它的次數。
我聽到有人在談論GC等待“最佳時機”的到來。 但是,這是一個空的應用程序,甚至不是enter_frame事件,也沒有時間讓您空閑以刪除剩余的27,000 K(38,000-11,000)。
坐在新的低點,如果我們重新添加矩陣,我們將回升到975,000K。
也就是說,比第一次多出13,000K。 如果我重復此添加/刪除操作,它將保持不變,最高可達975,000 K,最高可達38,000K。
請記住,此應用程序中沒有任何操作。 我的實際應用程序具有650mb的原始位圖數據,更不用說100mb的SWF解析和500mb的XML類(僅在初始化代碼中使用)。
我讀過很多遍,即使手動調用GC也很糟糕,更不用說6次了。 但是,如果我不發布,任何Matrix3D都不會發布。
有人怎么處理呢? 在初始化結束時,我是否只需調用GC 6次?
編輯:
我正在發布模式下測試差異,以及是否在沒有System.gc()調用的情況下進行了測試,如果沒有從閃存中釋放內存,至少要正確地重新使用它。 它最終會實現,但具有更高的新足跡。 完整列表位於990,000 K,清除后達到1,050,000K。
這是用於最初花費我們962,000 K RAM的數據的。 那是90MB的內部閃存GC內存。 更不用說忽略它永遠不會將內存還給操作系統(沒有顯式GC調用)。
Actionscript的GC很奇怪,沒什么好說的,
如果您嘗試使用類似的方法,它會有所幫助(我剛剛進行了測試,GC在第一次嘗試(按鍵單擊)時就清除了內存),只是將Array更改為Vector以更快地進行測試,所以同樣會發生數組也是。 在這種情況下,我的環境是FlashCC。
package
{
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.geom.Matrix3D;
import flash.net.LocalConnection;
import flash.system.System;
import flash.utils.setTimeout;
public class MemoryTesting extends Sprite
{
var list:Vector.<Matrix3D> = null;
function MemoryTesting()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
public function onKeyDown(event:KeyboardEvent):void
{
var matrx:Matrix3D;
var index:int
if (event.keyCode == 13)
{
trace(System.totalMemory, "starting to fill...")
if (list == null)
{
list = new Vector.<Matrix3D>
for (index = 0; index < 1000000; ++index)
{
matrx = new Matrix3D();
list.push(matrx);
}
}
trace(System.totalMemory, " done...")
}
else
{
if (list)
{
trace(System.totalMemory, " preparing to delete...")
list.splice(0, list.length);
list = null;
}
//force GC to work normally, it really helps (at least in my case)
try
{
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
}
catch (e:*)
{
}
setTimeout(function()
{
trace(System.totalMemory, " deleted")
}, 50)
}
}
}
}
這個奇怪的片段在大多數情況下確實有幫助
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}
這是令人討厭的文章: http ://gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.