1

新しくリリースされたソフトウェア製品用に、基本的な iOS アプリ (FB 4.6 を使用して Adob​​e Flex/AIR で構築) をリリースしました。私は、基本的にアプリの機能性を向上させるために、アプリの機能強化を任されています。

私はかなりの数の改善を行いましたが、途中でさまざまな程度の成功を収めました。しかし、私は脱線します。

これまで検出されていなかった、アプリ内の重大なメモリ リークと思われるものを発見しました。

アプリの最初のリリースでは、多くのことはできませんでしたが、ほとんどの目的には十分でした。しかし、より多くの機能が含まれるようになったので、私のテストでは、iPad での動作が少し遅いことに気付きました。私はそれをデバイスの問題であると考え、第一世代の iPad は新しい iPad ほど強力ではないと推測した。

同僚の iPad 3 でアプリをテストしたところ、同じ種類の速度の問題が見つかりました。FB のプロファイラーでアプリを実行したところ、非常に大量のメモリを使用しているように見えました。確かに、このアプリはモバイル プラットフォームを対象としており、プロファイラーは Windows 内の Flash Player でアプリを実行していましたが、それが問題だと思います。

アプリケーションに表示される最初のビューは、単なるログイン画面です。アプリケーションの起動時にグラフを確認したところ、メモリ使用量がかなり低く推移していましたが、突然 120MB に急増しました。これには、ユーザーからの入力はありませんでした。ログインしたりビューを切り替えたりすると、使用量が 2 倍、さらには 3 倍になり、減少することはありません。

確かに、私はリソースの使用についてそれほど意識していなかったかもしれませんが、オブジェクトなどをクリアしようとしてきました。

バックエンド機能のほとんどは、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 サービスを呼び出すより効率的な方法はありますか? 私は何を間違っていますか?

前もって感謝します!

4

1 に答える 1

1

やっとわかった気がする!!

この投稿は、同じ問題に遭遇する可能性のある他の人のための公開サービスです。

なぜ Web サービスがメモリ使用量の急増を引き起こすのかはわかりませんが、回避することができました。私の場合、使用量は依然として 120MB をわずかに下回りますが、違いは、ビューを切り替えたときに、以前のように 2 倍または 3 倍にならないことです。

私を正しい方向に導いてくれた Amy のおかげです。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 に設定してください。安全のために、トークンと操作のためにこれを行いました。

アプリのメモリ使用量を徹底的にテストしたわけではありませんが、一見したところ、指数関数的に増加していませんでした。また、ガベージ コレクションが開始されたときにメモリ使用量が減少するのを見たことさえあると思います.

于 2013-04-03T22:31:17.240 に答える