ホームページ開発ツール>Xojo / Real Studio Trial and Error・CocoaのDeclareでのメモリリークに対処する

 Xojo / Real Studio Trial and Error

CocoaのDeclareでのメモリリークに対処する

目次
 はじめに

 以下は、Xojo Cocoaビルドについての話題です。

 XojoでCocoaのDeclareを使う上での留意点の一つである、メモリリークについて調べてみました。

 なお検証には、Xojo 2016 Release 3 / Xcode 8.2を用いています。(Mac mini mid 2010 + OS X 10.11.6 El Capitan)
(注:Xcodeは本体ではなく、付属のInstrumentsのみを使用。)


 経緯

 Xojoは、ネイティブな機能を使う限りにおいては、ユーザがメモリリーク対策を行う必要は原則ありませんが、CocoaのDeclareを利用する場合は、自分で行う必要があります。
 Cocoaにおけるメモリリークについては、例えば以下のサイトが参考になります。(他にも沢山あります。)

 参考サイト(1):こたつつきみかん » メモリ管理

 基本としては、自分でalloc/initしたものは自分で解放する、ということのようですが、解放してはいけないものを解放したり、寿命が切れる前に解放してしまうと異常終了する(しかも、Xojoのデバッガでは拾えない)ので、できればリークを起こしたことを確認後に解放のコードを追加する方が、(スジのいいやり方とは言えませんが)楽で確実です。
 問題は、どうやって調べるかですが、ググっているうちに以下がヒットしました。

 参考サイト(2):xojo memory leaks - Xojo Forum

 どうも、Xcode付属のInstrumentsのLeaksテンプレートがXojoでも使える、ということのようです。
 Instrumentsの操作方法は、以下の公式ドキュメントが参考になります。(他にも沢山あります。)

 参考サイト(3):Instrumentsユーザガイド - Apple Developer(PDFへのリンク)

 あとは実際にInstrumentsを使って、確かめてみることにしました。


 Leaksを使ってみる

 以下は、Xojoの新規プロジェクトをそのままビルドしたアプリ(バイナリ)を対象として、Instruments(のLeaksテンプレート)を実行したものです。
S Shot1
 見ると、1項目(ウィンドウメニュー関連)リークしていますが、これはXojo内部での話?なので、ユーザは潰せないようです。

 次に、以前作ったプロジェクトを試してみました。(こちらです。)
 Leaksは、一連の処理が一段落すると、その時点でのリーク項目を知らせてくれます。
 以下は、プリントメニューを選択し、ダイアログが表示されて、しばらく経った状態です。(クリックして拡大
S Shot2
 結構リークしていますが、MallocやCFStringといった項目は、あまり気にしなくてもいいようです。
 というのも、これらはリークしたインスタンスに付帯した項目のようで、元のインスタンスを解放してやると、表示されなくなります。

 リークを起こすようなインスタンスの管理は、本来自分で行うべきでしょうが、Leaks上で辿ることもできます。
 さすがにXojoとは連携できないので、ソースの表示は無理ですが、リークを起こしたメソッドは特定できます。
 上記例でいうと、左ペインでクリックした項目(NSConcreteAttributedString)は、右ペインのスタックリストからNSTextViewPrintクラスのGetHeaderStringメソッドで発生していることが分かります。

 当該ソースはここにある通りです。
 ここでpgfをalloc/initしていますが、この項目はsetObject:forKey:でNSMutableDictionaryにセット(この時点でコピーが行われる)後は使用しませんので、リリースしなければいけません。

 参考サイト(4):iOSアプリ開発のメモリ管理で気をつけること - A Day In The Life
 参考サイト(5):iPhoneアプリケーション開発: Objective-Cにおけるメモリ管理

 ちなみにattrもalloc/initしていますが、これは戻り値で、以降も使用しますので、ここでリリースしてはいけません。
 対策したソース(抜粋)は以下の通りで、// clean up直下の2行を追加しています。
…
// ParagraphStyleをDictionaryにセット
setObject(option, pgf, "NSParagraphStyle")

// clean up
Declare Sub release Lib "Cocoa" Selector "release" (receiver As Ptr)
release(pgf)

// スタイル付テキストを生成
…

 同様に、PrintContent、DrawPageBorderWithSize、GetFooterSrringも対策します。(対策後のソースはこちら
 これで、(ウィンドウメニュー関連の1項目表示後、)ダイアログ表示の段階までのリークは発生しなくなりました。
 なお、印刷を実行すると別項目がリークしますが、こちらは継続調査中です。


 おわりに

 Leaksは、全てのリークを拾うことはできないようです。
 なので、Allocationsでのメモリ使用量をモニタリングする等して、総合的に判断した方がいいようです。


 お世話になったサイト

 貴重な情報をご提供頂いている皆様に、お礼申し上げます。(以下、順不同)

 参考サイト(1):こたつつきみかん » メモリ管理
 参考サイト(2):xojo memory leaks - Xojo Forum
 参考サイト(3):Instrumentsユーザガイド - Apple Developer(PDFへのリンク)
 参考サイト(4):iOSアプリ開発のメモリ管理で気をつけること - A Day In The Life
 参考サイト(5):iPhoneアプリケーション開発: Objective-Cにおけるメモリ管理


 更新履歴

 2017.01.16 新規作成


[Home]  [MacSoft]  [Donation]  [History]  [Privacy Policy]  [Affiliate Policy]