Mar*_*wie 6 flash garbage-collection actionscript-3
上下文:一个大型AS3应用程序可能会遭受频繁但不可预测的"停止世界"垃圾收集暂停.当一个人罢工时,可能需要30秒或更长时间才能结束.
这在测试中不会发生,但它可能在生产中.
问题:Flash VM是否有可用于检测和记录此类事件的日志记录?我在这里借鉴Java的经验.我已经广泛阅读了Flash GC机器的功能(使用标记/扫描进行参考计数),但我正在寻找一些真实的遥测技术,因为我知道标记/扫描GC事件可以"阻止世界".
你是对的.垃圾收集器暂停应用程序执行.
Flash Runtime垃圾收集器算法在标记正在使用的内存时以递增方式运行.它在收集未使用的内存部分时暂停应用程序执行.在增量收集周期结束时发生的暂停可能比期望的更长,并且在某些程序中可以观察到或听到.
从参考
据我所知,没有直接的方法可以知道GC是否运行.但是可以执行测试功能ENTER_FRAME并检查自上次函数调用以来是否已收集垃圾.自上一帧以来有效.
通过Dictionary可存储弱引用键的内容,可以查看是否已收集对象.如果是这种情况,垃圾收集必须运行.在下面的类中,我创建了一个新对象,以便稍后检查它是否已被收集.
package
{
import flash.display.Sprite;
import flash.utils.Dictionary;
public class GCTest
{
private static var dict:Dictionary = null;
public static function didGCRun():Boolean
{
if ( dict == null ) {
dict = new Dictionary(true);
}
var hasKeys:Boolean = false;
for ( var obj:* in dict ) {
hasKeys = true;
break;
}
if ( hasKeys ) {
return false;
}
else {
dict[new Sprite()] = null;
return true;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过检查每个帧,您将知道是否gc中风
addEventListener(Event.ENTER_FRAME, onEnterFrame);
private function onEnterFrame(event:Event):void
{
var gcRan:Boolean = GCTest.didGCRun();
}
Run Code Online (Sandbox Code Playgroud)
您还可以通过检查内存使用情况来监视垃圾回收.文档建议使用System.freeMemory()
分配给Adobe Flash Player或Adobe AIR且未使用的内存量(以字节为单位).分配的内存(System.totalMemory)的未使用部分随着垃圾收集的发生而波动.使用此属性可以监视垃圾回收.
我会结合使用这个值 System.totalMemoryNumber()
结合其他方法,记录实际帧速率或代码块的执行时间可能会有所帮助.这可以通过将程序"正常运行时间"存储在变量中并在稍后比较它来实现.
使用 getTimer()
对于处理ActionScript 3.0的Flash运行时,此方法返回自ActionScript 3.0(AVM2)的Flash运行时虚拟机启动以来经过的毫秒数.
var startTime:int = getTimer();
// execution or frame change
var executionTime:int = getTimer() - startTime;
Run Code Online (Sandbox Code Playgroud)
当在每个帧上使用时,您可以将其stage.frameRate与此进行比较并检查是否存在差异.
缓解暂停的可能性可能是建议垃圾收集器手动执行.System.pauseForGCIfCollectionImminent(imminence:Number = 0.75)如果实际紧迫性高于参数值,将暂停程序执行.
紧迫性定义为收集者认为标记的距离,因此触发收集暂停的距离有多近.此函数的紧急参数是一个阈值:仅当实际紧迫度超过阈值时才会调用垃圾收集器.否则,此调用立即返回而不采取任何操作.
通过调用具有低紧迫值的此函数,应用程序指示它愿意接受必须完成相对大量的标记.另一方面,较高的迫近值表示只有在标记接近完成时才应暂停应用程序.通常,在前一种情况下,暂停比在后一种情况下更长.
imminence:Number(默认值= 0.75) - 介于0和1之间的数字,其中0表示不太迫近,1表示最迫切.小于0的值默认为0.25.大于1.0的值默认为1.0.NaN默认为0.75
从参考