如何使用flash.sampler.getSamples测试垃圾收集

如何使用flash.sampler.getSamples测试垃圾收集,flash,apache-flex,actionscript-3,actionscript,Flash,Apache Flex,Actionscript 3,Actionscript,我正在尝试对内存管理进行单元测试。到目前为止,我有一个半可行的解决方案,使用flash.sampler.getSamples来获取具有相同id值的NewObjectSamples和DeleteObjectSamples的数量之间的差异 该测试如下所示: startSampling(); new Foo(); new Foo(); new Foo(); forceGC(); pauseSampling(); countAllocations(Foo); // returns 1, should r

我正在尝试对内存管理进行单元测试。到目前为止,我有一个半可行的解决方案,使用
flash.sampler.getSamples
来获取具有相同id值的NewObjectSamples和DeleteObjectSamples的数量之间的差异

该测试如下所示:

startSampling();
new Foo();
new Foo();
new Foo();
forceGC();
pauseSampling();
countAllocations(Foo); // returns 1, should return 0
countAllocations()方法获取特定类的NewObjectSamples和DeleteObjectSamples数量之间的差异:

    public static function countAllocations(type:Class):int
    {
        var count:int = 0;
        var allocations:Dictionary = new Dictionary();
        for each (var sample:Sample in getSamples()) {
            if (sample is NewObjectSample) {
                var newObjectSample:NewObjectSample = sample as NewObjectSample;
                if ((newObjectSample.type == type) && (newObjectSample.object != null)) {
                    allocations[newObjectSample.id] = true;
                    count ++;
                }
            } 
            else if (sample is DeleteObjectSample) {
                var deleteObjectSample:DeleteObjectSample = sample as DeleteObjectSample;
                if (allocations[deleteObjectSample.id]) 
                    count --;
            }
        }
        return count;
    }
forceGC()方法使用LocalConnection hack强制垃圾收集:

public static function forceGC():void {
        try {
            new LocalConnection().connect("bdebdd96-7bf8-407b-bec9-8336b2b0c329");
            new LocalConnection().connect("bdebdd96-7bf8-407b-bec9-8336b2b0c329");
        }
        catch (error:Error) {
        }
}
单步执行代码显示:

NewObjectSample Foo id=1 (count = 1)
NewObjectSample Foo id=2 (count = 2)
NewObjectSample Foo id=3 (count = 3)
// NewObjectSamples related to the LocalConnection hack
DeleteObjectSample id=2 (count = 2)
DeleteObjectSample id=1 (count = 1)
// Where's wally #3??


由于没有对Foo的引用,我假设所有实例都是垃圾收集的,我的代码完全错误,因为我不了解采样是如何工作的。我尝试使用弱键词典,而不是使用弱键词典,因为它似乎不太像黑客,但现在我开始怀疑它是否值得麻烦。

尝试在连续帧上运行gc。我也有同样的问题。我花了大约2天的时间试图追踪一个我认为自己存在的内存泄漏(我使用弱键字典方法来检查它)。结果是第一次没有收集到它

尝试在连续帧上运行gc。我也有同样的问题。我花了大约2天的时间试图追踪一个我认为自己存在的内存泄漏(我使用弱键字典方法来检查它)。原来它只是第一次没有被收集到

这不值得回答,但根据我的经验,
新字典(true)
是可靠的。另外,您可以在发行版播放器中运行测试。@sean fujiwara True,我目前确实使用字典。我希望从中获得的好处是简单,不必在字典中为每个对象保留显式引用。如果使用调试播放器,可以使用
System.gc()
,而不是gc hack。此外,没有太多的方法来测试垃圾收集,因为您将进行的任何测试都是“createx,deletex”,除非您在其中添加了很多奇怪的情况,否则每次都可以运行。根据我的经验,添加更好的编码标准是GC的最佳方式,然后手动进行评测。@j-a-x感谢您的输入。其目的是将其用于测试驱动的开发——作为驱动一次性类开发的一种方式。能够在单元测试中测试内存泄漏,而不是使用运行时探查器,这也很好。我不使用
System.gc()
的原因是它只在下一个
EnterFrame
上运行收集器,而hack立即运行gc,这意味着测试不必是异步的,这意味着它们更简单。您想使用gc hack进行测试吗?处理复杂的(异步)测试,即使它可能更困难。不要使用本质上不可靠的东西进行测试。这不值得回答,但根据我的经验,
newdictionary(true)
是可靠的。另外,您可以在发行版播放器中运行测试。@sean fujiwara True,我目前确实使用字典。我希望从中获得的好处是简单,不必在字典中为每个对象保留显式引用。如果使用调试播放器,可以使用
System.gc()
,而不是gc hack。此外,没有太多的方法来测试垃圾收集,因为您将进行的任何测试都是“createx,deletex”,除非您在其中添加了很多奇怪的情况,否则每次都可以运行。根据我的经验,添加更好的编码标准是GC的最佳方式,然后手动进行评测。@j-a-x感谢您的输入。其目的是将其用于测试驱动的开发——作为驱动一次性类开发的一种方式。能够在单元测试中测试内存泄漏,而不是使用运行时探查器,这也很好。我不使用
System.gc()
的原因是它只在下一个
EnterFrame
上运行收集器,而hack立即运行gc,这意味着测试不必是异步的,这意味着它们更简单。您想使用gc hack进行测试吗?处理复杂的(异步)测试,即使它可能更困难。不要使用本质上不可靠的东西进行测试。感谢您的输入,但实际上我对使用的确切GC方法不太感兴趣,而更感兴趣的是如何使用问题标题中所述的getSamples()测量内存使用情况。即使使用System.GC(),问题仍然是如何使用采样器检查内存分配和取消分配。我的观点是,关于采样,我唯一要做的改变(除了跟踪所有
DeleteObjectSample
s)是在多个帧上运行它,而GC介于两者之间。你现在的问题是你缺少了第三个
Foo
,这可能是因为它还没有被收集,而不是你的代码有问题。你也可以从FlashPreloadProfiler中查看代码:如果我没记错的话,它会做一些这样的事情。只是检查一下问题,让它工作,因为有一些小错误,从一开始就阻止它工作。啊,我明白你的意思-这是有道理的。在赏金到期之前我无法尝试,但如果结果是正确的,我会以其他方式将赏金分配给你。@lukevanin。抱歉打断你的提问。我正试图联系你。您似乎知道如何在不使用保存框的情况下通过air下载内容。我真的需要帮助。但我不知道如何在这之外联系你。谢谢你,埃德。vizenor@gmail.comThanks对于输入,但实际上我对使用的确切GC方法不太感兴趣,而更感兴趣的是如何使用问题标题中所述的getSamples()测量内存使用情况。即使使用System.GC(),问题仍然是如何使用sampler.my point检查内存分配和取消分配