簡體   English   中英

AS3內存管理逆向工程

[英]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-降至255,000K。
  • 第二次GC呼叫-92,000K。
  • 第三名-52,000千
  • 第四名-42,000千
  • 第五-39,000千
  • 坐鎮38,000 K之后的第六次及以后的任何連續時間。

我聽到有人在談論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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM