Если объект собирает мусор во Flash, автоматически уменьшаются ли счетчики ссылок на объекты, на которые он ссылается? - PullRequest
2 голосов
/ 21 июня 2011

Я думал о Flash GC на днях и задал вопрос о том, как будет работать подсчет ссылок в следующем сценарии из 4 классов (предположим, GuiMain - это класс документов фильма):

package com.gui {     
import flash.display.MovieClip;         
public class GuiMain extends MovieClip {         
 private var button1Handle:Button1;         
 public function GuiMain() {             
  // constructor code             
  button1Handle = new Button1();             
  addChild(button1Handle);            
  killButton1();         
 }                 
 public function killButton1(){             
  removeChild(button1Handle);             
  button1Handle = null;         
 }     
}     
}



package com.gui {     
import fl.controls.Button;    
import flash.display.*;         
public class Button1 extends Sprite {         
 private var button2Handle:Button2;         
 private var tester:Test;         
 public function Button1() {             
  // constructor code            
  button2Handle = new Button2();             
  tester = new Test();         
 }     
}     
}



package com.gui {         
public class Button2 {         
 public function Button2() {             
  // constructor code         
 }     
}     
}


package com.gui {     
import flash.display.MovieClip;     
import flash.events.Event;             
public class Test extends MovieClip{         
 public function Test() {             
  // constructor code            
  addEventListener(Event.ENTER_FRAME, yellLoudly);         
 }                 
 public function yellLoudly(e:Event){                         
  trace("AAAH!!!");         
 }     
}     
}

КогдаЭкземпляры Button2 и Test создаются в Button1, и я ожидаю, что их счетчики ссылок будут увеличиваться.Вопрос в том, уменьшаются ли их счетчики ссылок соответственно, когда созданный ими объект Button1 удаляется из списка отображения и обнуляется?Я протестировал этот код, и слушатель событий в классе Test, похоже, отключился, но это не обязательно означает, что он или экземпляр Button2 имеют право на GC.Даже если бы они были, это могло бы быть только в Mark and Sweep, который медленнее, чем GC на основе подсчета ссылок.

Одним из очевидных решений было бы удаление класса слушателей из ссылок / нулевых ссылок, которые он делает, когданастало время удалить его следующим образом:

package com.gui {     
import fl.controls.Button;     
import flash.display.*;         
public class Button1 extends Sprite {         
 private var button2Handle:Button2;         
 private var tester:Test;         
 public function Button1() {             
  // constructor code             
  button2Handle = new Button2();             
  tester = new Test();         
 }                 
 public function destroyRefs(){                   
  button2Handle = null;                   
  tester.removeEventListener(Event.ENTER_FRAME, tester.yellLoudly);                   
  tester = null;            
 }     
}     
}

, но в реальной программе, где я могу работать с несколькими ссылками на один и тот же объект из разных классов (путем передачи исходных ссылок в конструкторах).) не приведет ли установка ссылки в одном классе к нулевому значению, что значение всех других ссылок на тот же объект также станет нулевым?Это, конечно, было бы нежелательно ...

Основной вопрос заключается в следующем: когда исключается единственная ссылка на Button1, все счетчики, на которые она ссылается, уменьшают свои счетчики ссылок (либо сразу, либокогда объект Button1 является сборщиком мусора)?

Кроме того, есть ли способ просмотреть все экземпляры объекта, которые существуют в режиме реального времени, и / или их значения счетчиков ссылок через отладчик Flash?Такой подробный профилировщик действительно помог бы разобраться с этими вопросами ...

спасибо, CCJ

Ответы [ 4 ]

3 голосов
/ 21 июня 2011

бесстыдная самореклама, но это должно вам помочь: http://divillysausages.com/blog/tracking_memory_leaks_in_as3

0 голосов
/ 22 июня 2011

ооо, хороший вопрос:)

Насколько я знаю, Mark и Sweep используются только для прослушивателей событий подсчета ссылок, поскольку они единственные, у кого могут быть «слабые слушатели». Все остальное - подсчет ссылок на память. По сути, вашей самой большой проблемой будет очистка прослушивателей событий, но если прослушиватели событий находятся в вашем классе (слушающие себя, или его дочерние элементы, или даже внешние события), они должны быть правильно обработаны GC, если объект разыменовывается во всем приложении ( не храните его где-нибудь еще).

Если вы позволяете объекту или свойствам быть публично видимыми, другие классы могут ссылаться на них, и это может помешать GC вашего класса (это действительно зависит от того, как на него ссылаются и все). Единственное, что нужно для борьбы, это попытаться инкапсулировать как можно больше (один класс обрабатывает свою собственную разыменование; изучите IDisposable), чтобы другие не могли ссылаться и пытаться придерживаться хороших методов кодирования (предотвращение спагетти-кода).

0 голосов
/ 21 июня 2011

Эта презентация http://onflex.org/ACDS/AS3TuningInsideAVM2JIT.pdf содержит довольно хорошее описание того, как сборка мусора реализована в AVM2 (виртуальная машина с AS3).

0 голосов
/ 21 июня 2011

Я не думаю об AS3 с точки зрения подсчета ссылок. Если эти объекты, созданные в Button1, доступны только через Button1, то они имеют право на GC, как только вы отключите Button1. Исключение составляют слушатели событий, вы должны очистить их, иначе эти объекты не будут удалены. Flash не учитывает, что объекты больше не слушают.

...