---------------------我只是个搬运工--------------------------

还有人在用以下方法强制调用GC吗?你out了。

try {

   new LocalConnection().connect('foo');

   new LocalConnection().connect('foo');

} catch (e:*) {}

 

网上能查到的帖子,都说AS3调用GC的时间是不确定的。但我可以很负责人的告诉大家,Adobe对GC调用的时机是有明确说明的。网上的帖子嘛,你懂的,很多情况下是一个人写了,就有许多人转,不管对不对。于是好多错误和过时的东西,至今还广为流传。

正好今天有空,我就来解释一下GC时机问题,顺便纠正一下网传的许多关于GC的错误。

调用GC的时机:

程序调用GC的时机有3种

1、当totalMemory发生爆发性增长时。这个时机很难把握,这也就是为什么,一开始从事AS3开发的那一代程序员普遍认为GC时机是不确定的原因。当然,现在已经不是那么回事了,GC有了另一个明确的调用时机,详见第三条。

2、当程序发生异常时。我在一开始提到的那个,连续尝试建立两个连接同一个目标的LocalConnection对象,来进行强制GC,也就是利用了这种方法。其实,要用这种方法强制GC的,你可以随时用throw new Error("String")来触发,不必两次连接那么麻烦。当然,网传就是这样,第一个人写帖子说要用这方法触发GC,不动脑筋的程序员就将其发扬光大,沿用至今了。当然,关于强制GC,还有一个很特殊,也很好用的方法,我会在稍后公布。

3、当freeMemory达到某一数值时。关注内存管理的朋友们一定知道,Syetem类下关于内存的属性有4个,但大多数人都只关注totalMemory,而很少有人会关注freeMemory。AS3中,已经释放不用的对象,内存不是被立即回收的,而是将此对象加入到GC列表等待GC,而这些在GC列表中的对象所占用的总内存数,就是freeMemory。当freeMemory达到某一确定的值时,程序调用GC。不过要说明的是,这个值虽然是确定的,但在不同运行时环境中,这个值是不同的,要在具体环境中测试得出。

 

注:Flash申请和注销内存的最小单位是2k字节,所以你输出那些memory属性时,看到的都是一个2048的整倍数,所以当你申请了一块内存时,不一定会看到totalMemory的数值增加了;另一方面,在你释放了某项资源,并调用强制GC后,freeMemory的数值也没有减少之类,这都是正常现象。

 

好了,讲完了GC调用。现在我来讲讲一些特殊的内存回收情况。

比如,netStream的close方法,loader的unloadAndStop方法,还有bitmapData的dispose方法,等,一些特殊对象的释放方法,调用后都能直接释放内存。这是程序员可以直接控制的释放内存时机。

不过要做下说明,就是这些对象其实不是自己释放的内存,而仍是把释放的资源放入了GC列表等待回收。但因为这些资源占用的内存较大,通常都会直接引发freeMemory超过警戒线,而直接触发了一次GC,造成内存立即被回收的假相。当然,你不了解这一点也没关系,效果都是一样的。

 

最后,回过头来讲讲内存强制回收。

一般在正式发布的程序中,不会使用强制GC,因为对象资源释放了,等到GC时自然会被回收,如果没有释放,强制GC也不会回收。调用强制GC没有任何意义,只是给CPU增加负担。

然而,在调试程序时,强制GC就变得有意义了,因为有时候程序员需要了解某一个对象是否完全被释放了,加入GC列表中了。这个时候,强制GC就很有用了。当然,我从来不用那个两次连接的方法来强制GC,而是调用System对象的gc方法,强制GC。

注:此方法只适用于调试器版的FlashPlayer,也就是你调试程序时用的那个。不过这就够了。

看到这里,也许有人就要骂了,有这么好用的强制GC的方法了,为什么网上的帖子却都告诉你要用两次连接的办法?别激动,因为早期的AS3并不提供这个方法。老一辈在AS3领域的开荒者们,条件是很艰苦的,你原谅他们吧。

 

最后,我要写上一句,我写这帖子的时间——今天是2012年9月19日,如果有朋友要转发我的这个帖子,也请把这个时间转发在内。等一两年之后,当这个帖子所讲的内容过时时,请大家酌情参考。

---------------------我只是个搬运工--------------------------

源地址:http://bbs.9ria.com/thread-149825-1-1.html

分类:

技术点:

相关文章: