在Adobe Flash Player 10中,AS3的内部垃圾回收机制是什么?程序员可以强迫FP回收内存吗?答案是否定的,但是有很多方法。
强制垃圾回收的代码
MoonSpirit在天地回写了一篇关于强制垃圾收集的文章:[作为黑客技术]由垃圾收集器强制执行。本文中的示例显示,使用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;//容器spriteprivate 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,手动回收两次变为9KinitBitmapDataView( );//峰值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;}}}}

首先,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的内部垃圾收集机制后,我们可以回答为什么创建两个无用的LocalConnections并连接到不存在的地址,故意引发异常并捕获它们,我们可以强制垃圾收集吗?由于LocalConnection是AS3中的一个内存密集型对象,因此两次创建此类对象并尝试进行连接的内存开销足以要求Flash Player从操作系统重新申请内存,而FP将尝试在应用之前回收它。原理就是这么简单。您可以单独使用LocalConnection,也可以使用其他消耗更多内存的对象。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-361549-1.html
利比亚
而且也是最好强的
谁也不会像喝可乐一样和它