Как я могу проверить, была ли переменная собрана сборщиком мусора? - PullRequest
2 голосов
/ 20 февраля 2011

Я пытаюсь настроить тест, который скажет мне, существует ли переменная в памяти или нет.Я сталкиваюсь с проблемой моей вложенной функции, сохраняющей локальную переменную, которая называется «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 ]

4 голосов
/ 20 февраля 2011

Ваша String не может быть собрана, поскольку новый экземпляр не создан, но значение берется из пула констант, который заботится о String, Number, int и т. Д.

Если вы создаете новые Class, Object, Array и т. Д. ... их можно собирать, и вы можете отследить их простым способом: поместить свой экземпляр в качестве слабого ключа в словарь.

Таким образом, когда происходит сбор мусора, ключ будет удален из словаря. Вот пример кода для тестирования и живой код: 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 голос
/ 24 февраля 2011

Простой метод, похожий на метод Патрика:

Тест с useWeakReferences, чтобы увидеть, когда объект собирается в мусор

  1. Создание пользовательского класса, содержащего обработчик событий, прослушивающий ENTER_FRAME (используйтеслабая ссылка).
  2. Обработчик экземпляра отслеживает вывод до тех пор, пока для экземпляра объекта не будет установлена ​​нулевая ссылка экземпляра объекта.

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.
    }
}
0 голосов
/ 20 февраля 2011

Ну, во-первых, должен BeeDead не выходить за рамки указанного кода. вывод "переменная не мертва" - это правильное состояние. В AS3 для вашей вложенной функции правильно сохранить эту переменную.

для вашего другого вопроса. Если var указывает на объект, вы всегда можете проверить его на наличие объекта == null (если сборщик мусора получил его, он будет нулевым)

Есть что-то еще, но я не могу вспомнить.

Вот очень четкий ответ относительно объема этой вложенной функции. Вложенные функции, как они собирают мусор во Flash ActionScript 3?

0 голосов
/ 20 февраля 2011

Я не верю, что есть способ сделать это (или я по крайней мере не знаю об этом), потому что сборка мусора настолько произвольна. Вот хорошая статья про сборщик мусора флеш плеера. http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...