【转】Flash Player的垃圾内存回收机制:能否强制回收?
2010-11-04 21:56
573 查看
在Adobe Flash Player 10中,AS3的内部垃圾回收机制是怎样的?程序员可以强制FP回收内存吗?答案是否定的,但有方法。
MoonSpirit在天地会撰写过一篇关于强制垃圾回收的文章:[as hack技术]垃圾回收机强制执行。文中例证,使用LocalConnection连接非法地址,并捕获导常,可以强制进行垃圾回收。sban在MoonSpirit的基础上,简单修改了一下代码,如下:
[/code]
首先sban不调用doClearance方法,手动单击两次FB的“运行垃圾回收器”按钮(为什么要两次,后面解答),内存二下从4111K降到了9K!如下图所示,雷人吧。
然后呢,sban调用doClearance方法,这次无论是否手动回收,内存占用无变化,如下图所示,这说明doClearance方法已经强制了垃圾内存回收,它作用了!
那么,为什么创建两次没用的LocalConnection可以强制回收内存呢?
当Flash Player发现已经申请的内存不够用时,它会再向操作系统申请一大块内存。但在申请之前,请注意,FP会尝试进行垃圾内存回收。那么它是如何回收的呢?
Flash Player在内部使用懒惰式引用计数回收方案进行垃圾内存回收,懒惰式指:FP并不会一次把所有可以回收的对象全部回收,它一次仅会回收一部分,如果内存不够用,它会向操作系统申请,如果系统无内存了,它会再次回收,如果全部回收了仍不够用,Game Over!引用计数指:FP在内部给每个对象标记一个记号,当没有任何对象引用此对象时,它即是可以被回收的;如果一个容器内有许多相互关联的对象,当把这个容器从显示列表中移除,并且置为null后,它也是可以被回收的。
在小节2中,sban问到为什么要手动单击两次“运行垃圾回收器”按钮,这是由于FP垃圾回收机制的懒惰性造成的。
在清楚了FP的内部垃圾回收机制之后,我们便可以回答,为什么创建两次没用的LocalConnection,并且连接并不存在的地址,故意抛出异常然后捕获,可以强制垃圾回收呢?因为,在AS3中LocalConnection是比较占用内存的对象,两次创建该类对象并尝试进行连接的内存开销大小足以请Flash Player重新向操作系统申请内存,而在申请之前,FP会尝试回收。原理即是这么简单,非独使用LocalConnection可以,其它较耗内存的对象也可以。
sban 2008年5月 北京。转载请注明作者及出处,非商用。本文属于《AS3 Expert》。
强制垃圾内存回收的代码
AS3程序员没有办法强制Flash Player进行垃圾回收。MoonSpirit在天地会撰写过一篇关于强制垃圾回收的文章:[as hack技术]垃圾回收机强制执行。文中例证,使用LocalConnection连接非法地址,并捕获导常,可以强制进行垃圾回收。sban在MoonSpirit的基础上,简单修改了一下代码,如下:
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.net.LocalConnection; /** * * @author sban http://sban.biz/ * 修改自MoonSpirit的强制垃圾回收测试代码 */ public class GarbageCollectionTest extends Sprite { private const SQR_AMOUNT : int = 10000; //方块数量 private var _container_sp : Sprite;//容器sprite private var _sqrList: Array;//所有方块的引用 //强制垃圾回收使用的对象 private var conn1 :LocalConnection; private var conn2 :LocalConnection; public function GarbageCollectionTest() { init( ); } private function init( ) : void{ _container_sp = new Sprite( ); addChild(_container_sp); //initNoBitmapDataView( );//峰值4111K,手动回收两次变为9K initBitmapDataView( );//峰值14K,最小为14K,手动回收基本无变化 } //初始化 通过通常手段 显示 private function initNoBitmapDataView( ) : void { layoutTenThousandSqr( ); unLayoutTenThousandSqr( ); _sqrList = null; removeChild(_container_sp); _container_sp = null; } //初始化 通过BitmapData快照 显示 private function initBitmapDataView( ) : void { layoutTenThousandSqr( ); unLayoutTenThousandSqr( ); _sqrList = null; removeChild(_container_sp); _container_sp = null; doClearance( ); } private function layoutTenThousandSqr( ) : void { _sqrList = new Array( ); for(var i : int = 0; i < SQR_AMOUNT; i++){ _sqrList.push(new Sprite()); _sqrList[i].graphics.beginFill(0xff0000); _sqrList[i].graphics.drawRect(0,0,100,100); _sqrList[i].graphics.endFill(); _container_sp.addChild(_sqrList[i]); } } //不显示 private function unLayoutTenThousandSqr( ) : void { for(var i : int = 0; i < SQR_AMOUNT; i++){ _container_sp.removeChild(_sqrList[i]); delete _sqrList[i]; } } //精髓,垃圾回收机强制调用 private function doClearance( ) : void { trace("clear"); try{ conn1 = new LocalConnection(); conn1.connect("sban garbage collection 1"); conn2 = new LocalConnection(); conn2.connect("sban garbage collection 1"); }catch(e :*){} finally{ conn1 = null; conn2 = null; } } } }
[/code]
首先sban不调用doClearance方法,手动单击两次FB的“运行垃圾回收器”按钮(为什么要两次,后面解答),内存二下从4111K降到了9K!如下图所示,雷人吧。
然后呢,sban调用doClearance方法,这次无论是否手动回收,内存占用无变化,如下图所示,这说明doClearance方法已经强制了垃圾内存回收,它作用了!
那么,为什么创建两次没用的LocalConnection可以强制回收内存呢?
3. AS3垃圾内存回收机制
在Flash Player初始化运行时,会向操作系统申请一大块内存,如果程序很小,有可能根本用不了这么多内存,但FP在开始时不考虑这些,大多数情况下,第一次申请的内存总是不够用的。第一次申请的内存大小,与操作系统、浏览器环境有关。当Flash Player发现已经申请的内存不够用时,它会再向操作系统申请一大块内存。但在申请之前,请注意,FP会尝试进行垃圾内存回收。那么它是如何回收的呢?
Flash Player在内部使用懒惰式引用计数回收方案进行垃圾内存回收,懒惰式指:FP并不会一次把所有可以回收的对象全部回收,它一次仅会回收一部分,如果内存不够用,它会向操作系统申请,如果系统无内存了,它会再次回收,如果全部回收了仍不够用,Game Over!引用计数指:FP在内部给每个对象标记一个记号,当没有任何对象引用此对象时,它即是可以被回收的;如果一个容器内有许多相互关联的对象,当把这个容器从显示列表中移除,并且置为null后,它也是可以被回收的。
在小节2中,sban问到为什么要手动单击两次“运行垃圾回收器”按钮,这是由于FP垃圾回收机制的懒惰性造成的。
在清楚了FP的内部垃圾回收机制之后,我们便可以回答,为什么创建两次没用的LocalConnection,并且连接并不存在的地址,故意抛出异常然后捕获,可以强制垃圾回收呢?因为,在AS3中LocalConnection是比较占用内存的对象,两次创建该类对象并尝试进行连接的内存开销大小足以请Flash Player重新向操作系统申请内存,而在申请之前,FP会尝试回收。原理即是这么简单,非独使用LocalConnection可以,其它较耗内存的对象也可以。
sban 2008年5月 北京。转载请注明作者及出处,非商用。本文属于《AS3 Expert》。
相关文章推荐
- 【转】Flash Player的垃圾内存回收机制:能否强制回收?
- 转载:《AS3 Expert》- Flash Player的垃圾内存回收机制:能否强制回收?
- 【转】Flash Player的垃圾内存回收机制:能否强制回收?
- Flash Player垃圾回收机制强制执行
- Java内存分配及垃圾回收机制
- 二.Java的初始化机制、垃圾回收机制和内存分配机制
- 【Java】关于JVM运行时内存空间、JVM垃圾回收机制
- 深入了解C#系列:谈谈C#中垃圾回收与内存管理机制
- Java的内存和垃圾回收机制
- js的垃圾回收机制和内存分配
- Java的垃圾回收机制,GC,和变量的创建和删除的关系(即变量的作用域,for循环中的某个变量,出了for循环再引用就会报错了,因为该变量已经被从内存中删掉了)
- GC回收与内存管理机制,垃圾回收
- JVM垃圾回收机制及内存
- Python的垃圾回收机制(二)之内存模型
- JVM内存模型及垃圾回收机制
- Java内存与垃圾回收机制
- JavaScript中的垃圾回收机制与内存泄露
- 1.JVM垃圾回收机制-哪些内存需要回收
- 二.Java的初始化机制、垃圾回收机制和内存分配机制
- php内存管理机制、垃圾回收机制