1

所以我使用 Haxe 已经有一段时间了,最​​近我突然想到,就内存清理而言,我并没有真正了解其他一些非闪存目标上发生的情况。我的意思是“更新所有内容并通过设置对 null 的引用来转储它让我感觉存在内存泄漏,但我似乎无法找到我正在寻找的文档。

具体来说,我使用了相当数量的字典/地图。像这样:

var items:Map<String, MyObject> = new Map();

items.set("someKey", new MyObject(args...));

// Later
items["someKey"].doSomething();
items["someKey"].setVal(2);
...

// When Finished
items.remove("someKey");

那里的最后一行只是将我的对象转储到遗忘的某个地方,并希望得到垃圾收集(至少在 Flash 目标上)。

我编写了一个小程序,只是为了查看 Flash/Neko 上的清理操作,然后为其他目标更改它,但我什至看不到Flash Neko 目标上的清理。这是项目代码:

    package;

import openfl.display.Sprite;
import openfl.events.Event;
import haxe.ds.StringMap;

import openfl.events.KeyboardEvent;
import openfl.ui.Keyboard;

class Main extends Sprite 
{
    private var keypressID:Int;
    private var itemID:Int;
    private var dict:StringMap<Sprite>; // Using this since I read Map<String, T> just compiles to StringMap<T>.

    public function new() 
    {
        super();

        addEventListener(Event.ENTER_FRAME, init);
    }

    private function init(event:Dynamic):Void
    {
        removeEventListener(Event.ENTER_FRAME, init);
        // Entry point.

        keypressID = 0;
        itemID = 0;
        dict = new StringMap();

        stage.addEventListener(KeyboardEvent.KEY_UP, keyPress);
    }

    private function keyPress(event:Dynamic):Void
    {
        if (Std.is(event, KeyboardEvent) && cast(event, KeyboardEvent).keyCode == Keyboard.A)
        {
            trace('ID: $keypressID - Adding Item');
            keypressID += 1;

            for (i in 0...10000)
            {
                itemID += 1;
                dict.set('$itemID', new Sprite());
            }
        }
        else if (Std.is(event, KeyboardEvent) && cast(event, KeyboardEvent).keyCode == Keyboard.R)
        {
            trace('ID: $keypressID - Removing Items');
            keypressID += 1;

            removeItems();
        }

        // Force garbage collector to run.
        else if (Std.is(event, KeyboardEvent) && cast(event, KeyboardEvent).keyCode == Keyboard.C)
        {
            trace('ID: $keypressID > Starting GC');
            keypressID += 1;

            forceGarbageCollection();
        }
    }

    private function removeItems()
    {
        trace('ID: $keypressID > Remove All Item');

        for (val in dict.keys())
        {
            dict.remove(val);
        }

        dict = new StringMap();
    }

    private function forceGarbageCollection():Void
    {
        neko.vm.Gc.run(true);   // This does not work.
    }
}

我在 Windows 和任务管理器下运行它,我的 neko 进程只会增长而不会缩小。按下“A”时,它会快速达到 500MB。然后我'R'删除对项目的所有引用,但即使我强制GC,它们似乎也不会被收集。

我还尝试存储带有事件侦听器的 openfl.util.Timer 对象以进行跟踪,但它们似乎也从未被收集。他们只是继续追踪。现在我怀疑这可能是因为事件侦听器引用,但我确信我已经在其他 AS3 内存泄漏跟踪代码中看到了这个技巧。

我错过了什么或做错了什么?

编辑:

我已经修改了上述问题以反映这一点,但我对 Flash 播放器有误。使用 flash.system.System.gc() 在 Flash 播放器中运行时,我确实得到了要回收的内存;看来问题可能是我的问题仍然解决的 neko 特有的。

4

0 回答 0