озадачивает проблема сбора мусора - PullRequest
0 голосов
/ 25 сентября 2010
1) var x1:X = new X();
2) var x2:X = new X();
...
3) x1.z = new SWFLoader(...);
...
4) x2.z = x1.z;
5) x1.z = null
6) x1 = null;

Последнее утверждение бесполезно, потому что утверждение 4 гарантирует, что x1 и все остальное, что оно содержит, никогда не будут собирать мусор, пока существует x2.z. Кто-нибудь еще думает, что это странно? Это было большим шоком и недостатком для меня того, что мне нужно было сделать. Есть ли обходной путь вообще?

Единственная причина, по которой это имеет смысл, заключается в том, что все в x1 хранилось в непрерывной памяти или что-то в этом роде, но когда вы говорите «x1.z = new ...» в большинстве языков, это подразумевает его запуск и выделение нового блока память в другом месте и возвращение указателя на него (указатель, который впоследствии также назначается для x2.z.) Я всегда интерпретировал «ссылку» в actionScript как «указатель».

Конечно, некоторые могут сказать, что вы все равно можете удалить все в x1 по отдельности. Но если бы не оператор 4 выше, оператор 6 пометил бы все в x1 для удаления.

(Примечание: единственная причина, по которой я поместил утверждение 5, заключается в том, чтобы сказать флеш-плееру: «Я действительно больше не интересуюсь x1.z», но это не имело значения.)

Ответы [ 2 ]

1 голос
/ 26 сентября 2010

Если я правильно понял ваш вопрос, вы говорите, что следующий код должен пропустить x1. Но это не так. Как вы проверяете, что x1 не имеет права на сбор? Можете ли вы опубликовать какой-нибудь рабочий код, который воспроизводит проблему?

package {
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.net.URLLoader;
    import flash.system.System;
    import flash.utils.Dictionary;
    import flash.utils.setInterval;

    public class test extends Sprite
    {

        private var _dict:Dictionary = new Dictionary(true);

        private var x1:Foo;
        private var x2:Foo;

        public function test()
        {
            testGC();
            setInterval(function():void { 
                traceCount();
            },100);         
        }

        private function testGC():void {
            x1 = new Foo();
            x2 = new Foo();

            _dict[x1] = true;
            _dict[x2] = true;

            x1.z = new URLLoader();
            x2.z = x1.z;

            x1 = null;


        }

        private function traceCount():void {
            var count:int = 0;
            for each(var i:* in _dict) {
                count++;
            }
            trace(count);
            System.gc();
        }

    }
}

import flash.net.URLLoader;

class Foo {

    public var z:URLLoader;
}
0 голосов
/ 26 сентября 2010

Я только что попытался продублировать это новым кодом и не смог, так что я в растерянности. Оригинальный код теперь перевернут, и класс был намного больше, чем тестовый сценарий, который я только что придумал. Думаю, мне лучше закрыть это. Вот тестовый сценарий, который я только что выполнил, FWIW:

package my_components 
{

  import mx.controls.SWFLoader;

  public class Test {

    public var arr:Array = new Array();

    public var z:SWFLoader;

    public function Test() {
      for (var n:int=0; n<1000000; n++)
        arr.push(n);
    }  

  }

}       

private var x1:Test;
private var x2:Test;

private function InitWR(fnCFG:String = null):void {

  try { 
    new LocalConnection().connect('foo'); 
    new LocalConnection().connect('foo'); 
  } catch (e:*) {} 

  Dumper.info(System.totalMemory.toString());   

  x1 = new Test();
  x1.z = new SWFLoader();

  x2 = new Test();

  x2.z = x1.z;

  x1 = null;

  try { 
    new LocalConnection().connect('foo'); 
    new LocalConnection().connect('foo'); 
  } catch (e:*) {} 

  Dumper.info(System.totalMemory.toString());   

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