AS3 - 垃圾收集器什么时候运行?

ori*_*zil 6 flash garbage-collection actionscript-3

道歉,如果这是一个骗局; 我找不到它.

我已经在AS3垃圾收集器上阅读并理解了grant skinner的博客 - http://www.adobe.ca/devnet/flashplayer/articles/garbage_collection.html,但我的问题不在那里.

这是我的问题.

假设我写了一些AS3代码,如:

statementOne;
statementTwo;
Run Code Online (Sandbox Code Playgroud)

垃圾收集器是否有可能在我的两个语句期间或之间运行,或者仅在我的"用户"代码完成并将控制权返回到闪存后运行?

我们有一个有时很慢的A-Star代码块,我想消除GC作为潜在的罪魁祸首.代码块显然比我上面的例子更复杂,但它不涉及任何事件或其他异步的东西.

蒂亚,猎户座

Gun*_*r47 6

垃圾收集器没有线程,因此一般来说,在代码运行时它不会运行.然而,有一个例外情况并非如此.

new如果内存用完关键字将调用垃圾收集器.

您可以运行此代码来观察此行为:

var vec:Vector.<*> = new Vector.<*>(9001);
for (;;) {
    vec[0] = new Vector.<*>(9001);
    vec = vec[0];
}
Run Code Online (Sandbox Code Playgroud)

内存使用率会迅速上升到最大值(对我来说是1GB)然后一直持续到时间中断.


fen*_*mas 5

这里有很多好的答案,但我认为一些细微之处尚未得到解决.

  1. Flash播放器实现了两种垃圾收集.一个是引用计数,其中Flash保持对每个对象的传入引用的计数,并且知道当计数达到零时,可以释放对象.第二种方法是标记扫描,其中Flash偶尔会搜索并删除隔离的对象组(其中对象相互引用,但组作为一个整体没有传入引用).
  2. 作为规范,任何时候都可能发生任何类型的垃圾收集.播放器不保证何时释放对象,并且标记扫描甚至可以分散在几个帧上.此外,无法保证GC的时间在Flash播放器版本或平台甚至浏览器之间保持不变.因此,在某种程度上,了解有关如何触发GC的信息并不是非常有用,因为您无法知道您的知识有多广泛适用.
  3. 除了前面的观点,一般来说,标记扫描不常见,只在某些情况下触发.我知道某些播放器/操作系统配置,其中标记/扫描可以每N秒触发一次,或者当播放器超过总可用内存的P%时,但这是很久以前的事情,细节将会改变.相反,参考计数GC可能经常发生 - 至少在帧之间.我不认为我已经看到它们被证明更频繁地发生,但这并不意味着它不会发生(至少在某些情况下).

最后,关于您的具体问题:根据我的经验,GC不太可能与您的性能问题有关.在循环期间可能会发生引用计数的GC处理,但通常这是一件好事 - 这种集合非常快,并且可以保持内存使用的可管理性.仔细管理您的参考文献的重点是确保这种GC及时发生.

另一方面,如果在循环期间发生标记/扫描,那肯定会影响您的性能.但这是相对难以辨认和易于测试的.如果你在PC上进行测试并且你的应用程序没有经常进入数百MB的内存使用量(测试System.totalMemory),你可能根本就没有得到任何标记/扫描.如果你有它们,应该很容易验证相关的暂停是否很大,不经常,并且总是伴随着内存使用量的大幅下降.如果这些事情不正确,你可以忽视GC是你问题的一部分.