Flex内存释放记录

来源:互联网 发布:网络与新媒体 考研好吗 编辑:程序博客网 时间:2024/06/06 07:46

1.不知道什么时候才会出现的GC

2.内存泄露

个人认为,flashPlayer内存占用高很大程度上不是因为无法手动GC,而是因为设计上的失误(是天真地以为flash/flex像C#/java 那样有防止内存泄露的完善的机制)而导致无穷无尽的内存占用。如果你经常被这些问题困扰,那么你有幸了,因为你遇到了猫粮,遇到了能帮你把应用内存占用降 下来的文章。
 


测试环境的建立

 

为了测试环境的纯净,在数据输出方面我只使用了Trace。

 

下面是MemoryMonitor的代码:(可怜徐灿的代码被我整容了...大概只保留了定时器还有CallBackFunction)

 

这个东西主要用于每隔一秒就检测一次内存,并且执行一次callBackFunction。

 

复制内容到剪贴板代码:

 

<?xml version="1.0" encoding="UTF-8"?>

 

<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"

 

    creationComplete="start()">

 

<mx:Script>

 

<![CDATA[

 

    import flash.utils.getTimer;

 

    private var timer:Timer;

 

    public var interval:int = 1000;

 

    public var callbackFunction:Function = null;

 

    private function timerHandler(event:TimerEvent):void

 

    {

 

        trace("Time:"+getTimer()+"cur:"+System.totalMemory)

 

        if (callbackFunction != null)

 

            callbackFunction();

 

    }

 

    public function start():void

 

    {

 

        timer = new Timer(interval);

 

        timer.addEventListener("timer", timerHandler);

 

        timer.start();

 

    }

 

    public function stop():void

 

    {

 

        timer.stop();

 

        timer.removeEventListener("timer", timerHandler);

 

        timer = null;

 

    }

 

]]>

 

</mx:Script>

 

</mx:Canvas>


主程序代码
这个就是上面提到的两贴代码的宿主了。我们只需要更改enterFrameHandler这个函数就能对数据进行测试。
徐灿的原版代码将在最后奉上.....
复制内容到剪贴板代码:
<?xml version="1.0" encoding="UTF-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
    xmlns:local="*"> 
    <mx:Script> 
        <![CDATA[ 
            import mx.controls.VideoDisplay; 
            private function enterFrameHandler():void 
            { 
                //TODO:测试内存占用的代码写在这里
        }            
        ]]> 
    </mx:Script> 
<local:MemoryMonitor callbackFunction="enterFrameHandler" /> 
  <mx:ViewStack id="abc" /> 
</mx:Application>
 


 

新建Object+内存回收
复制内容到剪贴板代码:

private function enterFrameHandler():void
{
var o:Object = new Object();
MyGC.GC();
}

 


 

内存回收+设置为null的flash内存占用
复制内容到剪贴板代码:

private function enterFrameHandler():void
{
var o:Object = new Object();
o = null;
MyGC.GC();
}

 


加载外部文件,不关闭,内存回收
private function enterFrameHandler():void
{
var flvplay:VideoDisplay = new VideoDisplay();
this.addChild(flvplay);
flvplay.source = "phone.flv";
flvplay.play();
MyGC.GC();
}

 


 

关闭外部文件但是不移除显示对象
private function enterFrameHandler():void
{
var flvplay:VideoDisplay = new VideoDisplay();
this.addChild(flvplay);
flvplay.source = "phone.flv";
flvplay.play();
flvplay.close();
MyGC.GC();
}

 



只移除显示对象
private function enterFrameHandler():void
{
var flvplay:VideoDisplay = new VideoDisplay();
this.addChild(flvplay);
flvplay.source = "phone.flv";
flvplay.play();
this.removeChild(flvplay);
}


彻底清除引用的对比
没有设置null版
private function enterFrameHandler():void
{
var flvplay:VideoDisplay = new VideoDisplay();
this.addChild(flvplay);
flvplay.source = "phone.flv";
flvplay.play();
flvplay.close();
this.removeChild(flvplay);
MyGC.GC();
}
 


 

设置null版
private function enterFrameHandler():void
{
var flvplay:VideoDisplay = new VideoDisplay();
this.addChild(flvplay);
flvplay.source = "phone.flv";
flvplay.play();
flvplay.close();
this.removeChild(flvplay);
flvplay = null;
MyGC.GC();
}
添加+移除+内存回收
这个最搞笑,越来越少越来越少......
private function enterFrameHandler():void
{
var s:String = Math.random().toString();
this.addEventListener(s,abc);
this.removeEventListener(s,abc);
function abc(){}
MyGC.GC();
}
viewStack对比
上面的是Flex3 SDK的,下面的是Flex2 Hotfix3的SDK
徐灿说Flex2SDK的viewStack有bug,但是这样测试好像看不出什么问题..大家如果想深究的话就要自己测试一下
当然代码里面能发现问题,这些就不好说了..

private function enterFrameHandler():void
{
var flvplay:VideoDisplay = new VideoDisplay();
abc.addChild(flvplay);
flvplay.source = "phone.flv";
flvplay.play();
flvplay.close();
abc.removeChild(flvplay);
MyGC.GC();
}
总结
这次的测试就暂时到这里
我个人的感觉就是:
1.开了什么就要关掉什么
2.设置为null这一做法是没啥作用的,有没有被引用系统自己清楚,自己YY也没用
3.GC长做,特别是在清理的时候,这样能保证内存在第一时间被回收。
希望本文能对大家有点帮助


<!--①楼帖间广告开始-->


关于视频的,就是必须close了再new才能保证flv已经占的内存被释放……不然会造成内存泄露。

任何新addChild进来的东西关闭的时候都要removeChild掉。

还有就是FLEX 2 SDK里只要牵扯到ViewStack的组件都有先天性的内存泄露。这个问题在FLEX 3 SDK中得到了解决。

使用Module的要注意,不是只要unload了模块就等于把里面全部资源都释放了。必须把里面的东西手动清除。

比如我那个例子里面的,都removeAllChildren了。如果module里有正在动的东西或者什么的,他光unload那个module只是说 明把他从显示上去掉,里面的东西没有消除引用,所以必须unload的时候也把module里的东西removeAllChildren了

原创粉丝点击