所以我一直在使用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特有的问题,我的问题仍然存在。