首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AS3内存管理逆向工程

AS3内存管理逆向工程
EN

Stack Overflow用户
提问于 2014-01-16 17:16:31
回答 1查看 412关注 0票数 2

有没有人知道AS3实际上是如何处理垃圾收集的?在我正在开发的游戏中,我有太多的问题在释放内存。

做了一个小演示:

代码语言:javascript
复制
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调试器11.4r402。看着任务管理器,没有按下键,调试器闲置在11,000 K。

按a(添加10Mil Matrix3D类)最多可达962,000 K。

按另一个键(删除对矩阵的引用并对数组进行赋值)取决于我按它多少次。

  • 我们第一次把GC -降到25.5万K。
  • 第二个GC呼叫- 92,000 K。
  • 第三- 52,000 K.
  • 第四- 42,000 K
  • 第五-39 000 K.
  • 第六次&连续坐38,000 K。

我听到人们谈论GC在等待“合适的时机”来收集。但是这是一个空应用程序,甚至不是一个enter_frame事件,您没有足够的时间让它空闲着去删除剩余的27,000 K (38,000 - 11,000)。

在新的低点,如果我们再加上矩阵,我们会移动到975,000 K。

也就是说,比第一次多13,000 K。如果我重复这个添加/删除,它将保持不变,返回到975,000 K,下降到38,000 K。

请记住,这个应用程序中没有发生任何事情。我的实际应用程序有650 My的原始位图数据,更不用说解析100 My的SWF和仅用于初始化代码的500 My的XML类了。

我已经多次读到,即使手动调用GC也是错误的,更不用说6次了。但是如果我不放的话,Matrix3D就不会发布了。

有人怎么处理这件事?我要不要在初始化结束时给GC打6次电话?

编辑:

我在发布模式下测试不同之处,以及在没有System.gc()调用的情况下,如果内存不能从闪存中释放出来,那么是否至少要正确地重用它。它最终做到了,但是有了一个新的,更高的足迹。一个完整的列表位于990,000 K,清理它需要1,050,000 K。

这是最初花费我们962,000 K内存的数据。这是90 of的内部闪存GC内存。更不用说忽略它永远不会将内存返回给操作系统(没有显式的GC调用)。

EN

回答 1

Stack Overflow用户

发布于 2014-01-16 18:22:53

Actionscript的GC很奇怪,没什么可说的,

如果您尝试使用类似的方法,它会有所帮助(我刚刚测试并GC在第一次尝试时清除内存(键单击)),只需将Array更改为Vector,测试速度就会更快,同样的情况也应该发生在Array上。在这种情况下,我的环境是FlashCC。

代码语言:javascript
复制
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)

        }
    }
}

}

这个奇怪的片段在大多数情况下都有帮助。

代码语言:javascript
复制
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}

以下是freat的文章:2.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21168475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档