我知道探究者的问题可能很普遍,但在这里我有一个非常具体的问题和例子。
我知道在以下代码中(取自Joshua's question),无数个 circle 对象实例被添加到 hostComponent 。这显然会导致应用程序逐渐放缓。
我的问题是,当我运行Flash Builder Profiler时,我究竟在哪里看到问题出在哪里?
要试用它,请创建一个新的Flex 4项目,并粘贴以下代码:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
initialize="onInit()" viewSourceURL="srcview/index.html">
<fx:Script>
<![CDATA[
import mx.core.UIComponent;
import mx.effects.Fade;
import spark.effects.Move;
private var hostComponent:UIComponent;
private function onInit():void{
hostComponent = new UIComponent();
hostComponent.id = "circleHostComponent";
}
/* Add circle UIComponent objects to the hostComponent.
Move and Fade the circle objects */
private function onTimerEvent(event:TimerEvent):void{
var yPos:Number = Math.ceil(Math.random()*100);
var radius:Number = Math.ceil(Math.random()*5); //1-12
var effectAlpha:Number = Math.random()*0.5 + 0.2 // 0-1
var effectDuration:Number = Math.ceil(Math.random()*3000) + 1000;
var circle:UIComponent = new UIComponent();
circle.graphics.beginFill(0x1C75BC, effectAlpha);
circle.graphics.drawCircle(90, yPos, radius);
circle.graphics.endFill();
hostComponent.addChild(circle);
var moveEffect:Move= new Move(circle);
moveEffect.xBy = 300;
moveEffect.duration = effectDuration;
moveEffect.play();
var fadeEffect:Fade = new Fade(circle);
fadeEffect.alphaFrom = 1;
fadeEffect.alphaTo = 0;
fadeEffect.duration = effectDuration;
fadeEffect.play();
this.addElement(hostComponent);
}
private function onClick():void{
startButton.enabled = false;
var t:Timer = new Timer(100, 0);
t.start();
t.addEventListener(TimerEvent.TIMER, onTimerEvent);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button id="startButton" label="Click to Start" click="onClick()" />
</s:Application>
答案 0 :(得分:10)
首先,在使用应用程序后,我会查看“内存使用情况”面板:
请注意,内存越来越多。 有一个“运行垃圾收集器”按钮强制GC。但是,单击它时,内存不会减少。
下一步是确定罪魁祸首。为此,您可以使用“实时对象”面板:
看起来像是,通过一些Vector实例,一切看起来都很好。 默认情况下,许多类都从活动对象datagrid中过滤掉。幸运的是,可以指定显示和隐藏哪些类。 默认情况下,flash.x.x包中的所有类都是隐藏的。从过滤后的列表中删除它们会给桌面带来一些有趣的东西:
注意Graphics行:已经创建了871个实例,它们仍然在内存中!有了这些信息,您可以假设Graphics实例负责应用程序的减速。如果还过滤掉了mx。*类,您将看到有871个UIComponents实例。每次创建UIComponent时,都会有一个Graphics对象也会被实例化。
最后一步是删除屏幕上不再需要的每个UIComponent并查看是否有任何性能提升。
答案 1 :(得分:8)
现在你知道了内存问题的根源
要修复累积内存泄漏,请添加以下内容:
fadeEffect.play();添加
fadeEffect.addEventListener(EffectEvent.EFFECT_END, onEffectEnd);
并添加功能:
private function onEffectEnd(event:EffectEvent):void
{
trace(hostComponent.numChildren);
hostComponent.removeChild(event.target.target);
event.target.target = null;
}