垃圾回收测试

第一种情况,显示对象能被根访问

image

****属性的相互引用是很明确的,一般都是一个对象包含着若干属性,那么这个对象自然可以维持它的属性的引用。如果这个类不会被回收(能够被根访问),他的所有属性也都不会被回收。同样的,如果这个类可以被回收的话(不能被根访问),也就不会妨碍属性的回收。所以你并不需要将所有属性设置为null,除非你希望在对象存在时候就回收其属性的内存,这种需求基本不存在。

****至于在显示列表中的对象。既然根(stage)可以用getChildAt访问到自己的所有子对象,那么只要你在显示列表中,就肯定不会被回收。然而,如果显示对象的父层对象已经不再显示列表内,它的子对象就算还在父层对象之中也没有关系,因为它已经不能被stage访问到了。所以你不需要removeChild各层的全部对象,而只需要removeChild最高一层的父对象即可。

上面的2段话,我觉得在一起理解,不能分开来看。显示对象也是一个对象。flash player能否以标记清除法清除一个显示对象,这2个条件都要满足。

1、这个显示对象不能被根访问。(这里就不行,因为wd可以被根访问)

2、removechild这个显示对象。

所以上面这个例子用标记清除法是无法回收的,也就是说仅仅执行removechild是不够的。我们需要采用引用计数法来回收。

****因此,你要回收一个对象,只要保证没有任何对象引用它,而且他的方法没有被当做事件函数——或者说,他和程序的其他部分已经没有任何联系,它就满足了引用计数法的标准,就一定会被回收。做到这一点的方法就是一般说的“执行removeChild,removeEventListener,将对他的引用设置为null”。

如下:

private function rrreee(e:MouseEvent):void

{

this.removeChild(wd);

wd = null;

//移除事件侦听

}

回收前:

image

回收后:

image

看以上2张图的对比:

1、world实例及其所有子对象都被回收掉了。

2、wolrd中的ball实例被回收了,而文档类中的ball实例则没有被回收。因为没有removeChild(ball),改成如下这样既可:

(ball需要单独remove是因为其父对象文档类不会被回收,比如wd里的ball,因为wd被回收了,它也就被回收了)

private function rrreee(e:MouseEvent):void
{
    Tools.removeAllChild(this);
    wd = null;
}

(因为ball不能够被根访问,所以只需要removeChild就可以回收它)

第二种情况:显示对象不能被根访问,标记清除法

image

这个例子,wd不再能被根访问。满足标记清除法的要求。

image

暂时得出的结论:

1、1个对象只要不能够被根访问,在GC的时候它就会被回收掉。如果是显示对象的话,需要removeChild…

2、父对象能够被回收,里面的子对象就也能够被回收。所以不用每个对象都destory..

原文地址:https://www.cnblogs.com/axyz/p/2216206.html