メモリリークを調べたい

iPhoneアプリケーション開発ではガベージコレクションが使えないためJavaRubyのようなガーベージコレクションを備えている言語環境と異なりメモリリークの危険と常に隣り合わせです。しかし、iOS SDKにはメモリリークの検出をサポートするためのツールが用意されています。これを利用しない手はありませんね。

iOS SDKが提供するメモリリーク検出をサポートするツールは以下の2つがあります。

  • 静的コード解析を行う「静的アナライザ」
  • 動的プログラム解析を行う「Instruments」

静的アナライザはソースコードを静的に解析してメモリリークしていそうな箇所を推測する「静的コード解析」を、Instrumentsは実際にアプリを動かしながらメモリリークを検出する「動的プログラム解析」をそれぞれ行います。

静的アナライザ

静的アナライザを利用するには、Xcodeのメニューから「ビルド - Build and Analyze」を選択してプロジェクトをビルドするだけです。「Build and Analyze」を選択してアプリケーションをビルドすると、アプリケーションのビルドにつづいて静的アナライザによるソースコード解析が行われ、メモリリークしていそうなところをビルド結果へ出力してくれます。

例えば、以下のコードを静的アナライザに解析させてみると、

NSInteger n = (rand() % 7) + 1; // 1から7の間でランダムに取得
// messageをリリースしていないためメモリリークが発生する
NSString *message = [[NSString alloc] initWithFormat:@"%d人の侍", n];
NSLog(@"%@", message);

以下のような解析結果が得られます。
解析結果から変数messageがメモリリークしそうなことが分かります。

メニューから「Build - Analyze」を毎回選択するのが面倒な場合は、プロジェクトの設定内の「ビルドオプション - 静的アナライザを実行」にチェックを入れるといいでしょう。Xcodeのメニューから「ビルド - ビルド」を選択したときにも静的アナライザが実行されるようになります。


iOS SDK 4.1での静的アナライザの不具合

これを執筆している状況でのiOS SDKの最新バージョンであるiOS SDK 4.1では、アクティブSDKに「Simulator」を選択していると静的アナライザが正しく実行されない不具合があります。

アクティブSDKを「Simulator」ではなく「Device」を選択すると静的アナライザは正しく動作するため、この不具合が直るまでは静的アナライザをかけるときには「Device」を選択するようにしてください。

Instruments

次はInstrumentsを使ったメモリリーク検出です。動的プログラム解析を行うInstrumentsは静的アナライザでは見つけられないメモリリークを発見するのに役立ちます。

Instrumentsを使ったメモリリーク検出を利用するには、Xcodeのメニューから「実行 - パフォーマンスツールを使って実行 - Leaks」を選択すると、計測対象のiPhoneアプリとInstrumentsが起動します。

起動されたiPhoneアプリの操作中にメモリリークが発生すると、Instrumentsがそのメモリリークを検出しDetaileビューの「Leaks - Leadked Blocks」へとリークしたオブジェクトに関する情報を出力します。またExtended Detailでそのメモリリークしたオブジェクトがソースコード中のどこで生成されたかを確認することができます。