Actionscript 3 AS3-垃圾收集器何时运行?
道歉,如果这是一个骗局;我找不到它 我已经阅读并理解了grant skinner关于AS3垃圾收集器的博客- , 但我的问题不在这里 这是我的问题 假设我编写了一些AS3代码,如:Actionscript 3 AS3-垃圾收集器何时运行?,actionscript-3,flash,garbage-collection,Actionscript 3,Flash,Garbage Collection,道歉,如果这是一个骗局;我找不到它 我已经阅读并理解了grant skinner关于AS3垃圾收集器的博客- , 但我的问题不在这里 这是我的问题 假设我编写了一些AS3代码,如: statementOne; statementTwo; 垃圾收集器是否有可能在我的两条语句之间运行,或者只有在我的“用户”代码完成并将控制权返回给flash之后才运行 我们有一个有时很慢的A星代码块, 我想消除GC作为潜在的罪魁祸首。 代码块显然比我上面的例子更复杂, 但它不涉及任何事件或其他异步内容 蒂亚, Or
statementOne;
statementTwo;
垃圾收集器是否有可能在我的两条语句之间运行,或者只有在我的“用户”代码完成并将控制权返回给flash之后才运行
我们有一个有时很慢的A星代码块,
我想消除GC作为潜在的罪魁祸首。
代码块显然比我上面的例子更复杂,
但它不涉及任何事件或其他异步内容
蒂亚,
Orion您无法确定GC何时运行。如果您试图阻止某个内容被GC'd,请在某处保留对它的引用。据我所知,这没有文档记录。我有一种感觉,当你的代码被执行时,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);
}
}
}
包{
导入flash.display.Sprite;
导入flash.net.FileReference;
导入flash.system.system;
导入flash.utils.Dictionary;
导入flash.utils.setTimeout;
公共类测试扩展了Sprite
{
私有变量dict:Dictionary=新字典(true);
公共功能测试()
{
testGC();
setTimeout(函数():void{
traceCount();
},2000);
}
私有函数testGC():void{
var fileRef:FileReference;
对于(变量i:int=0;i<100;i++){
fileRef=新的FileReference();
_dict[fileRef]=真;
traceCount();
gc();
}
}
私有函数traceCount():void{
变量计数:int=0;
对于(变量i:*在目录中){
计数++;
}
跟踪(计数);
}
}
}
当涉及到FileReference
对象时,GC似乎特别贪婪(同样,这是根据我的经验得出的;据我所知,这没有文档记录)
现在,如果运行上述代码,即使显式调用System.gc()
,当函数在堆栈上时,对象也不会被收集:查看字典的计数(由于明显的原因,设置为使用弱引用),您可以看到它们仍然是活动的
再次跟踪此计数时,在不同的执行堆栈中(由对setTimeout的异步调用引起),所有对象都已释放
所以,我认为GC似乎不是您案例中表现不佳的罪魁祸首。同样,这只是一个观察,GC在这个测试中执行用户代码时没有运行并不意味着它永远不会运行。很可能不会,但由于没有记录在案,恐怕无法确定。我希望这有帮助 GC不会像示例中那样在同一堆栈/同一帧上的两条语句之间运行。内存将在执行下一帧之前释放。这就是大多数现代虚拟机环境的工作方式。垃圾收集器不是线程化的,所以一般来说,在代码运行时它不会运行。然而,有一个例外情况并非如此
new
关键字将在内存不足时调用垃圾收集器
您可以运行此代码来观察此行为:
var vec:Vector.<*> = new Vector.<*>(9001);
for (;;) {
vec[0] = new Vector.<*>(9001);
vec = vec[0];
}
var-vec:Vector.=新载体(9001);
对于(;;){
向量[0]=新向量(9001);
vec=vec[0];
}
内存使用率将迅速上升到最大值(对我来说是1GB),然后一直保持到时间截止。这里有很多好的答案,但我认为有一些微妙之处尚未解决