繁体   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