如何测试变量是否被垃圾收集?

时间:2011-02-20 09:02:08

标签: actionscript-3

我正在尝试设置一个测试,告诉我变量是否存在于内存中。我遇到了我的嵌套函数的问题,它保留了它使用的局部变量,名为“shouldBeDead”。这是我的最大努力,这对我不起作用,因为“shouldBeDead”变量仍然存在:

addEventListener(Event.ENTER_FRAME, isDeadYet);

function isDeadYet ($):void {
    var shouldBeDead = "not dead";

    if (!stage.hasEventListener(KeyboardEvent.KEY_DOWN))
        stage.addEventListener(KeyboardEvent.KEY_DOWN, test);

    function test($):void {
        trace("variable is " + shouldBeDead); // outputs: "variable is not dead"
    }
}

有没有办法测试内存中是否存在某些内容?

4 个答案:

答案 0 :(得分:4)

您的String无法被收集,因为没有创建新实例,但该值来自常规池,负责StringNumberint等。

如果你创建了一个新的ClassObjectArray等...这些可以被收集,你可以用一个简单的方法跟踪它们:把你的实例作为一个弱词进入词典。

因此,当发生收集发生时,密钥将从字典中删除。 这是一个用于测试的代码示例,以及实时代码:http://wonderfl.net/c/uP5T

import flash.utils.Dictionary;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.system.System;

var notGC:Dictionary=new Dictionary(true)
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown)

function traceNotGC():void{
        var cnt:int=0
        for (var key:Object in notGC) {
            cnt++
            trace("not garbaged : " + key)
        }
        if (cnt==0) trace("All garbaged")
}
function onKeyDown(e:Event):void{
    System.gc()
    traceNotGC()
}
function test():void{
    var str:String="not dead"  // string taken from the constant pool
                               // there is no allocation done

    var obj:Object={foo:"bar"} // creation of a new object that can be garbaged
    var arr:Array=[0,1,2]      // creation of a new array that can be garbaged

    notGC[str]=true
    notGC[obj]=true
    notGC[arr]=true

    traceNotGC()
}      
test()

答案 1 :(得分:1)

简单的技术,类似于Patrick的:

使用useWeakReferences进行测试以查看何时收集垃圾对象

  1. 实例化包含侦听'ENTER_FRAME'的事件处理程序的自定义类(使用弱引用)。
  2. 实例的处理程序跟踪输出,直到实例引用从实例化对象设置为null。

  3. package {
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        public class Main extends Sprite {
            private var livingObject:LivingObject;
    
    
            public function Main () {
                livingObject = new LivingObject(this, true);
                stage.addEventListener(MouseEvent.CLICK, killIt);
            }
            function killIt ($) {
                livingObject = null;
                trace('Attempted murder of livingObject.');
            }
        }
    }
    import flash.events.Event;
    class LivingObject {
        public function LivingObject ($main:Main, $immortal:Boolean) {
            $main.addEventListener(Event.ENTER_FRAME, proveImAlive, false, 0, $immortal ? false : true);
        }
        private function proveImAlive ($) {
             trace(this + ' LIVES!!!!!'); // Output stops when garbage collected.
        }
    }
    

答案 2 :(得分:0)

首先,shouldBeDead不在您列出的代码范围之外。输出“变量未死”是它的正确状态。 在AS3中,嵌套函数保留该变量是正确的。

您的其他问题。 如果var指向一个对象,你总是可以检查它是否为object == null(如果垃圾收集器已经得到它将为null)

还有别的东西,但我记不起来了。

这是一个关于嵌套函数范围的非常明确的答案。 Nested Functions, how are they garbage collected in flash actionscript 3?

答案 3 :(得分:-1)