ASP.NET Web服务导致Adobe Flex / AIR应用程序中的内存泄漏

时间:2013-04-02 20:39:41

标签: asp.net ios flex air adobe

我们已经为新发布的软件产品发布了一个基本的iOS应用程序(使用FB 4.6为Adobe Flex / AIR构建),我的任务是对应用程序进行增强,从根本上将其功能更多地提升到鼻烟。

我做了很多改进,在此过程中取得了不同程度的成功。但是,我离题了。

我发现应用程序中出现了严重的内存泄漏,直到现在都未被发现。

该应用程序的初始版本并没有做很多事情,并且它适用于大多数用途。但是现在它包含了更多的功能,我在测试中注意到它在iPad上有点迟钝。我认为它是一个设备问题,并猜测第一代iPad并不像新款iPad那么强大。

我们在同事的iPad 3上测试了该应用程序,并发现了同样的速度问题。我通过FB的分析器运行应用程序,发现它似乎使用了非常大量的内存。当然,这个应用程序是针对移动平台的,并且分析器在Windows中的Flash Player中运行应用程序,但我认为这是问题。

应用程序中显示的第一个视图只是一个登录屏幕。当应用程序启动时,我看到图形,内存使用率徘徊在相当低的水平,然后突然间,它飙升到120MB。没有来自用户的输入。登录或切换视图会使用量增加一倍甚至三倍,并且永远不会降低。

我会承认,也许我没有像过去那样对资源使用情况有所了解,但我一直试图清除对象,比如我去。

大多数后端功能是通过调用ASP.NET编写的Web服务完成的。使用Web服务向导将Web服务插入Flash Builder ...例如,URL为http://www.mydomain.com/MyWebService.asmx?WSDL

第一个“主页”视图不会调用任何Web服务功能,除非用户实际执行某些操作,例如按下按钮。我从视图的“fx:Declarations”部分中取出了Web服务声明,并注释掉了对它的任何引用,并再次尝试了探查器。

这一次,使用量限制为2MB。这是一个天文上的差异。

分析器显示99%的内存被“XML”类使用,这让我相信Web服务是问题所在。看起来好像是视图在启动时查询Web服务,并且正在使用大量内存来执行此操作。

我在这里遗漏了什么吗?是否有更有效的方法从AIR应用程序调用Web服务?我做错了什么?

提前致谢!

1 个答案:

答案 0 :(得分:1)

我想我终于明白了!!

这篇文章是针对可能遇到同样问题的其他人的公共服务。

我不确定为什么Web服务会导致内存使用量出现峰值,但我能够解决它。在我的情况下,使用率仍然低于120MB,但不同的是,当我切换视图时,它不会像之前那样加倍/加倍。

感谢艾米带领我朝着正确的方向前进。我基本上把所有的声明都拿出来给web服务,并在应用程序MXML文件中公开声明,就像这样。

public var ws:WebService = new WebService();

protected function viewnavigatorapplication1_preinitializeHandler(event:FlexEvent):void
{
    ws.loadWSDL("http://www.mydomain.com/MyWebService.asmx?WSDL");
}

然后在你的观点......

private var serviceOperation:AbstractOperation;
private var myToken:AsyncToken;

private function getData():void
{
    var firstName:String = "John";
    var lastName:String = "Smith";        

    serviceOperation = this.parentApplication.ws.getOperation("MyFunction");
    serviceOperation.addEventListener(FaultEvent.FAULT, fault);
    serviceOperation.addEventListener(ResultEvent.RESULT, result);

    myToken = serviceOperation.send(firstName, lastName);
}

public function result(data:Object):void
{
    switch(data.token)
    {
        case myToken:
            processResults(data);
            break;
        default:
            break;
    }
}

显然,确保删除事件侦听器并在完成后将对象引用设置为null。为了安全,我为令牌和操作做了这个。

我没有彻底测试应用程序的内存使用情况,但乍一看,它并没有成倍增加,我相信我甚至看到它在垃圾收集开始时就会崩溃。