我已经阅读并了解了关于AS3垃圾收集器的grant skinner博客 - http://www.adobe.ca/devnet/flashplayer/articles/garbage_collection.html, 但我的问题不在那里。
这是我的问题。
假设我写了一些AS3代码,如:
statementOne;
statementTwo;
垃圾收集器是否有可能在我的两个语句中或之间运行,或者它只在我的“用户”代码完成并将控制权返回到闪存后运行?
我们有一个有时很慢的A-Star代码块, 我想消除GC作为潜在的罪魁祸首。 代码块显然比上面的例子复杂, 但它不涉及任何事件或其他异步的东西。
TIA, 猎户
答案 0 :(得分:6)
垃圾收集器没有线程,所以一般来说,在代码运行时它不会运行。然而,有一个例外情况并非如此。
new
关键字将在内存不足时调用垃圾收集器。
您可以运行此代码来观察此行为:
var vec:Vector.<*> = new Vector.<*>(9001);
for (;;) {
vec[0] = new Vector.<*>(9001);
vec = vec[0];
}
内存使用率会迅速上升到最大值(对我来说是1GB)然后一直持续到时间中断。
答案 1 :(得分:5)
这里有很多好的答案,但我认为一些细微之处尚未得到解决。
最后,关于您的具体问题:根据我的经验,GC不太可能与您的性能问题有关。在循环期间可能会发生引用计数的GC处理,但通常这是一件好事 - 这种集合非常快,并且可以保持内存使用的可管理性。仔细管理您的参考文献的重点是确保这种GC及时发生。
另一方面,如果在循环期间发生标记/扫描,那肯定会影响您的表现。但这是相对难以辨认和易于测试的。如果您正在PC上进行测试,并且您的应用程序没有经常爬上数百MB的内存使用量(使用System.totalMemory
进行测试),那么您可能根本没有获得任何标记/扫描。如果你有它们,应该很容易验证相关的暂停是否很大,不经常,并且总是伴随着内存使用量的大幅下降。如果这些事情不成立,你可以忽视GC是你问题的一部分。
答案 2 :(得分:1)
据我所知,这没有记录。我感觉GC在执行代码时不会运行(也就是说,当你的代码在执行堆栈上时;每个框架,播放器为使用代码创建一个新的堆栈)。显然,这来自观察和我自己的Flash经验,所以我不会说这是100%准确。希望这是一个有根据的猜测。
这是一个简单的测试,似乎表明上述情况属实:
package {
import flash.display.Sprite;
import flash.net.FileReference;
import flash.system.System;
import flash.utils.Dictionary;
import flash.utils.setTimeout;
public class test extends Sprite
{
private var _dict:Dictionary = new Dictionary(true);
public function test()
{
testGC();
setTimeout(function():void {
traceCount();
},2000);
}
private function testGC():void {
var fileRef:FileReference;
for(var i:int = 0; i < 100; i++) {
fileRef = new FileReference();
_dict[fileRef] = true;
traceCount();
System.gc();
}
}
private function traceCount():void {
var count:int = 0;
for(var i:* in _dict) {
count++;
}
trace(count);
}
}
}
当涉及FileReference
个对象时,GC似乎特别贪婪(再次,根据我的经验;据我所知,这没有记录。)
现在,如果你运行上面的代码,甚至显式调用System.gc()
,当你的函数在堆栈上时,不会收集这些对象:你可以看到它们还活着看着字典的数量(由于显而易见的原因,它被设置为使用弱引用。)
当再次跟踪此计数时,在不同的执行堆栈中(由对setTimeout的异步调用引起),所有对象都已被释放。
所以,我认为GC似乎并不是你案件表现不佳的罪魁祸首。同样,这仅仅是观察,并且GC在此测试中执行用户代码时未运行的事实并不意味着它永远不会。可能,它不会,但由于没有记录,没有办法确定,我害怕。我希望这有帮助。
答案 3 :(得分:1)
GC不会像您在示例中那样在同一堆栈/同一帧上的两个语句之间运行。在执行下一帧之前,将释放内存。这就是大多数现代VM环境的工作方式。
答案 4 :(得分:0)
您无法确定GC何时运行。如果你试图阻止某些事情被GC进行,请在某处保留对它的引用。
答案 5 :(得分:0)
根据这个Tom from Gabob,足够大的孤立层次结构不会被垃圾收集。