ホームページ>開発ツール>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テンプレート)を実行したものです。
見ると、1項目(ウィンドウメニュー関連)リークしていますが、これはXojo内部での話?なので、ユーザは潰せないようです。
次に、以前作ったプロジェクトを試してみました。(こちらです。)
Leaksは、一連の処理が一段落すると、その時点でのリーク項目を知らせてくれます。
以下は、プリントメニューを選択し、ダイアログが表示されて、しばらく経った状態です。(クリックして拡大)
結構リークしていますが、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でのメモリ使用量をモニタリングする等して、総合的に判断した方がいいようです。
追記:いつの頃(どのバージョン)からかは不明ですが、ビルドしただけではエラーが出て使えなくなっていました。(確認済:Instruments v13.0 + macOS Big Sur)
調べたら、以下のサイトに解決法が示されていました。
参考サイト(6):M1. Instrument Leaks error "Failed… | Apple Developer Forums
お世話になったサイト
貴重な情報をご提供頂いている皆様に、お礼申し上げます。(以下、順不同)
参考サイト(1):こたつつきみかん » メモリ管理
参考サイト(2):xojo memory leaks - Xojo Forum
参考サイト(3):Instrumentsユーザガイド - Apple Developer(PDFへのリンク)
参考サイト(4):iOSアプリ開発のメモリ管理で気をつけること - A Day In The Life
参考サイト(5):iPhoneアプリケーション開発: Objective-Cにおけるメモリ管理
参考サイト(6):M1. Instrument Leaks error "Failed… | Apple Developer Forums
更新履歴
2021.10.08 おわりに、に追記を追加。
2017.01.16 新規作成
[Home] [MacSoft] [Donation] [History] [Privacy Policy] [Affiliate Policy]