简体   繁体   English

AS3内存管理逆向工程

[英]AS3 Memory Management reverse engineering

Has anyone figured out how AS3 actually handles garbage collection? 有人知道AS3如何真正处理垃圾回收吗? I'm having so many issues releasing memory in a game I'm developing. 我正在开发的游戏中释放内存有很多问题。

Made a small demo: 做了一个小演示:

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();
        }
    }
}

Running Flash Player Debugger stand-alone 11.4r402 in Windows 7. Watching the Task Manager, with no keys pressed, the debugger sits idle at 11,000 K. 在Windows 7中运行Flash Player Debugger独立的11.4r402。在没有按下任何键的情况下,看着任务管理器,调试器处于11,000 K的空闲状态。

Pressing a (adding 10Mil Matrix3D classes) takes it up to 962,000 K. 按下(添加10Mil Matrix3D类)会将其增加到962,000K。

Pressing another key (removing references to the Matrices and nulling the array) depends on how many times I press it. 按下另一个键(删除对矩阵的引用并使数组为空)取决于我按下它的次数。

  • The first time we call GC - drops to 255,000 K. 我们第一次称为GC-降至255,000K。
  • The second GC call - 92,000 K. 第二次GC呼叫-92,000K。
  • Third - 52,000 K. 第三名-52,000千
  • Forth - 42,000 K. 第四名-42,000千
  • Fifth - 39,000 K. 第五-39,000千
  • Sixth & any consecutive times after sits at 38,000 K. 坐镇38,000 K之后的第六次及以后的任何连续时间。

I hear people talking about the GC waiting for "opportune times" to collect. 我听到有人在谈论GC等待“最佳时机”的到来。 But this is an empty application, not even a enter_frame event and there is no amount of time you can leave it idle for it to remove the remaining 27,000 K (38,000 - 11,000). 但是,这是一个空的应用程序,甚至不是enter_frame事件,也没有时间让您空闲以删除剩余的27,000 K(38,000-11,000)。

Sitting at the new low, if we re-add the matrices we move back up to 975,000 K. 坐在新的低点,如果我们重新添加矩阵,我们将回升到975,000K。

That is to say, 13,000 K more than the first time. 也就是说,比第一次多出13,000K。 If I repeat this add/remove, it stays the same, going back up to 975,000 K and down to 38,000 K. 如果我重复此添加/删除操作,它将保持不变,最高可达975,000 K,最高可达38,000K。

Remember, there is nothing going on in this application. 请记住,此应用程序中没有任何操作。 My actual application has 650mb of raw bitmap data, let alone 100mb of SWF to parse and 500mb of XML classes that I only use in initialisation code. 我的实际应用程序具有650mb的原始位图数据,更不用说100mb的SWF解析和500mb的XML类(仅在初始化代码中使用)。

I've read multiple times that even calling GC manually is bad, let alone 6 times. 我读过很多遍,即使手动调用GC也很糟糕,更不用说6次了。 But none of the Matrix3D's will be released if I don't. 但是,如果我不发布,任何Matrix3D都不会发布。

How does anyone handle this? 有人怎么处理呢? Shall I just call GC 6 times at the end of initialisation? 在初始化结束时,我是否只需调用GC 6次?

Edit: 编辑:

I was testing in release mode for differences and whether, without the System.gc() call, that if it doesn't free the memory from flash, at the least re-uses it properly. 我正在发布模式下测试差异,以及是否在没有System.gc()调用的情况下进行了测试,如果没有从闪存中释放内存,至少要正确地重新使用它。 It does eventually, but with a new, higher footprint. 它最终会实现,但具有更高的新足迹。 With a full list sits at 990,000 K, clearing it takes it to 1,050,000 K. 完整列表位于990,000 K,清除后达到1,050,000K。

This is for data that initially cost us 962,000 K RAM. 这是用于最初花费我们962,000 K RAM的数据的。 That's 90MB of weird internal flash GC memory. 那是90MB的内部闪存GC内存。 Let alone ignoring that it won't ever give the memory back to the OS (without the explicit GC calls). 更不用说忽略它永远不会将内存还给操作系统(没有显式GC调用)。

Actionscript's GC is weird, nothing to say, Actionscript的GC很奇怪,没什么好说的,

If you'll try to use something like this, it helps (I just tested and GC clears out the memory on the very first try (key click)), Just changed Array to Vector to test more quicker, just the same should happen with Array too. 如果您尝试使用类似的方法,它会有所帮助(我刚刚进行了测试,GC在第一次尝试(按键单击)时就清除了内存),只是将Array更改为Vector以更快地进行测试,所以同样会发生数组也是。 My enviroment is FlashCC in this case. 在这种情况下,我的环境是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)

        }
    }
}

} }

This strange snippet really helps on most cases 这个奇怪的片段在大多数情况下确实有帮助

try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}

Here is the freat article: http://gskinner.com/blog/archives/2006/08/as3_resource_ma_2.html 这是令人讨厌的文章: 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