メモリーリークの調査をしている中で、<mx:Style>タグ を使用したサブ画面をメイン画面からポップアップ表示すると、サブ画面を閉じてもインスタンスが1つ残るというメモリーリークパターンが見つかったので覚え書きしておきます。

【確認環境】
Flex Builder 3.0.2
Flex SDK 3.5

以下は、問題が起こっているサンプルソースです。

 サブ画面【PopWindow.mxml】 では<mx:Style>タグを記述し、対象コンポーネントの"styleName"プロパティでスタイルを参照しています

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

<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"  horizontalAlign="center" verticalAlign="middle" width="400" height="300">
<mx:Style>
    .popLabel{
        color: #ff0000;
        font-size: 13;
        fontWeight: bold;
    }
</mx:Style>
<mx:Script>
    <![CDATA[
        import mx.managers.PopUpManager;
        
        private function onClickCloseBtn():void
        {
            PopUpManager.removePopUp(this);
        }
    ]]>
</mx:Script>
    <mx:Label text="下のボタンを押すとサブ画面が閉じます。" styleName="popLabel" />
    <mx:Button label="close" click="onClickCloseBtn()" />
</mx:TitleWindow>

 

 メイン画面【MainWindow.mxml】 ではサブ画面ポップアップ表示用のボタンを1つ用意します

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" verticalAlign="middle">
<mx:Script>
    <![CDATA[
        import mx.managers.PopUpManager;
        
        private function onClickHandler():void
        {
            var popWindow:PopWindow = PopWindow(PopUpManager.createPopUp(this, PopWindow, true));
            PopUpManager.centerPopUp(popWindow);        
        }
    
    ]]>
</mx:Script>
    <mx:Label text="下のボタンを押すとサブ画面をポップアップ表示します。" color="#ff0000" fontSize="13" fontWeight="bold" />
    <mx:Button label="Popup" click="onClickHandler()" />
</mx:Application>

サブ画面のポップアップ表示/閉じる を5回繰り返した後、ガベージコレクションをした結果をプロファイラーで見ると、 PopWindowのインスタンスが1つ残っています。
profile.pngのサムネール画像

ポップアップメモリーリークの解決策

解決策としては、以下の ①・② の2種類が候補に挙がり、結局②を採用しました。

① <mx:Style> に書いていた内容を該当コンポーネントのプロパティに追加する。
   <mx:Label text="下のボタンを押すとサブ画面をポップアップ表示します。" color="#ff0000" fontSize="13" fontWeight="bold" />
② Applicationファイルに外部ファイルとして作成したCSSを読み込ませ、それを参照させる。  

CSSファイル【Sample.css】

.popLabel{
    color: #ff0000;
    font-size: 13;
    fontWeight: bold;
}

メイン画面【MainWindow.mxml】

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" verticalAlign="middle">
<mx:Script>
    (略)
</mx:Script>

<mx:Style source="Sample.css"/>
    (略)
</mx:Application>

サブ画面【PopWindow.mxml】

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

<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"  horizontalAlign="center" verticalAlign="middle" width="400" height="300">



<mx:Script>

    (略)

</mx:Script>

    <mx:Label text="下のボタンを押すとサブ画面が閉じます。" styleName="popLabel" />

    <mx:Button label="close" click="onClickCloseBtn()" />

</mx:TitleWindow>


 

前回の記事で、Pythonのダウンロードまでをご紹介しました。
今回の記事では、ダウンロードしたPythonをインストールするところまでご紹介いたします。

ダウンロードした、「python-2.x.msi」を実行してます。
以下、実行した画面からの手順になります。

Pythonのインストール

1.Pythonを使用するユーザーを選択して、[Next]ボタンをクリックします。

PythonをインストールするWindowsの、全てのユーザーで利用できるようにするか、インストールを実行している現在のユーザーだけが利用できるようにするかを選択します。

選択する項目 使用できるユーザー
Install for all users 全てのユーザー
Install just for me (not available on Windows Vista) インストールを実行している現在のユーザーだけが利用可能

 

Python_Install_01.JPG

2.インストールするディレクトリーを選択し、[Next]ボタンをクリックします。

Python_Install_02.JPG

 3.インストールするコンポーネントを選択して、[Next]ボタンをクリックします。

Python_Install_03.JPG

    インストールが開始されます
Python_Install_04.JPG

4.インストールが完了したので、[Finish]ボタンをクリックします。

Python_Install_05.JPG

5.環境変数にインストールしたPATHを追加します。

環境変数にインストールしたPATHを追加してください。

Python_Install_06.JPG

 

Pythonの動作確認

1.コマンドプロンプトを起動し、「python」と入力します。

Python_Install_07.JPG

対話型シェルが起動されることを確認します。

2.コマンドを入力して、実行します。

試しに下記のコマンドを実行してみます。

>>> print "Hello python world."

Python_Install_08.JPG

表示されたらOKです。

3.Pythonの対話型シェルを終了します。

シェルを終了するには、Ctrl+Zを押下して、Enterキーを押下します。

Python_Install_09.JPG

このブログを見ていただいていると分かると思いますが、弊社でこのブログに記入している社員は、私も含めてAdobe の Flexに携わっている者ばかりです。
また、我々が携わったFlexの開発では、サーバーサイドをJavaで実装しているケースがほとんどです。

とはいえ、FlexでもサーバーサイドをLL(軽量言語)といった手法でも開発できるので、個人的に興味から、少し勉強を始めてみようと思っています。
まずは環境を整えてみようということで、Pythonの開発環境構築までをやってみることにしたので、私が行った開発環境構築までの手順を順次ご紹介しておきたいと思います。

第1弾は、ダウンロードまでをご紹介します。

今回、私が開発環境を構築するための前提条件は下記の通りになります。

  • OSはWindowsXPにインストールしています
  • Python公式サイトからインストールしているので、今回は日本語開発については意識していません
  • インストールしたPythonは、2.7 です

 

まずは、下記のPython公式サイトから開始します。
http://www.python.org/

1.TOPページ左側のメニューにある、「DOWNLOAD」をクリックします。

Python_Download_01.JPG2.インストールするPythonのバージョンを選択し、それぞれのインストーラーをダウンロードします。

今回は、Windows版のPython2をインストールするので「Python 2.x Windows installer」をクリックしてダウンロードします。

Python_Download_02.JPG【補足】
現在(2010年8月)Pythonのメジャーバージョンが2つ存在しています。
Python2とPython3の互換性については、下記の@ITの記事をご紹介しますので、詳細はそちらを参照ください。
よりPythonicなPythonを目指して

ダウンロードしたファイルで、Pythonのインストール(次の記事)を行います。

なんとなくですが、AMFのパケットの中身はどうなっているのだろうか?と思い立って調べてみました。

Googleで、「AMF パケット 仕様」で調べた結果、AdobeがAMF規格の仕様をPDFファイルで公開していたのを見つけました。

AMF0  http://opensource.adobe.com/wiki/download/attachments/1114283/JP_amf0_spec_121207.pdf
AMF3  http://opensource.adobe.com/wiki/download/attachments/1114283/JP_amf3_spec_121207.pdf

上のPDFですと私自身はいまひとつ分かりにくかったので、以下表にして簡単にまとめてみました。

AMFパケットの仕様

項目 説明
AMFパケットのバージョン  U16 AMFパケットのバージョン
AMF3=3
AMF0=0
ヘッダー数  U16 ヘッダーの数

 ヘッダー

※ヘッダー数分繰り返す

 ヘッダー名称サイズ  U16  ヘッダー名称の文字列長
 ヘッダー名称  UTF8 ヘッダー名称
文字列の長さはヘッダー名称サイズ
 ヘッダーのバイト長  U32 ヘッダーのバイト長
※わからない場合は(U32)-1
 value-type    
 AMFメッセージ数  U16  AMFメッセージ(ボディ)の数

 AMFメッセージ部

※AMFメッセージ数分繰り返す

 ターゲットURIサイズ  U16  ターゲットURIの文字列長
 ターゲットURIサイズ  UTF8  ターゲットURI名称
文字列の長さはターゲットURIサイズ
 レスポンスURIサイズ  U16  レスポンスURIの文字列長
 レスポンスURIサイズ  UTF8  レスポンスURI名称
文字列の長さはレスポンスURIサイズ
 メッセージのバイト長  U32  メッセージのバイト長
※わからない場合は(U32)-1
 value-type    

U8 = 符号なしのバイト、8 ビットのデータ、オクテット
U16 = ビッグエンディアン(network)バイトオーダで記された符号なしの16 ビット整数
U32 = ビッグエンディアン(network)バイトオーダで記された符号なしの32 ビット整数

 ドキュメントを読んでも、value-type の部分がいまいち謎です。

こういうことに今まで興味がわかなかったのは技術者としては?でしょうが、今回調べたことでAMFの中身についてある程度知ることができました。
そのうち、パケット解析ツールなどを使用して実際のデータを除いてみたいと思います。

JavaScriptと連携する際、ExternalInterfaceを使用しますがエラーハンドリングに関して注意が必要です。
以下はExternalInterfaceを使用した一般的なサンプルです。 エラーハンドリングの為にtry~catch~ステートメントを使用しております。

<mxmlコード>



	
		
	

	
		
	
	




<javaScript(index.template.htmlに実装)>

        function testFunc()
        {
        	window.alert("TestJs");
        	${application}.callBack();
        
        }

JavaScriptの呼び出しを行うイベントハンドラにおいて、「ExternalInterface.marshallExceptions = true;」という処理を実装しておりますが、実はmarshallExceptionsをtrueに設定しておかないと、コールバック先のイベントでthrowしたErrorが無視されてしまう為注意が必要となります。
marshallExceptionsの詳細は以下の通り。

ji100606-1.png

ただし、marshallExceptionsはFlexBUilder3から使用可能な機能なので、コンパイラのバージョンが3以前の場合は使用できません。
私の職場のシステムはFlex2立った為、marshallExceptionsを使用できず困った問題となってしまいました。エラー用のEventを作成しエラー時にdispatchする方法で回避致しましたが他に回避策は無いようです。

ExternalInterface使用時は注意が必要です。

<<前のページ 1234567891011

このブログについて

このブログは吉祥寺にあるブレインチャイルド株式会社の社員で投稿しています。
業務ではまってしまったことや発見したこと。
自分達で新たに学習してみようと思って勉強し始めたことなどを綴っています。
こんな社員が働いているブレインチャイルドに興味がわいててきたなら、是非お問い合わせください。
会社案内
求人案内
先輩のコメント