この記事は RubyMotion Advent Calendar 2012 の 10 日目の記事です。
つい最近ようやく RubyMotion API Reference が公開されましたが、みなさん見ていただけたでしょうか?RubyMotion のバグを取っていて、「このメソッド初めて見るんだけど何もの?」「ドキュメントが必要だよねぇ」みたいなやりとりをしながら、一生懸命リファレンスを作りました。
今回は autorelease_pool の使い方について書きます。
メモリサイクル
iOS では、ボタンをタップなどするとイベントが発生します。イベントの開始時に自動的にメモリプールを生成し、イベント終了時にプールをリリースします。このときメモリプールに登録されている不要になったオブジェクトが一緒にリリースされます。
RubyMotion で作られたアプリも、これに従って不要になったオブジェクトが破棄されていきます。
たとえば、イベント処理中に以下のような大量の一時的なオブジェクトを作成してみます。
1 2 3 4 5 |
|
Instruments.app でメモリ使用を確認すると、以下のようになります。
イベントが終了するまで一時的なオブジェクトは生存していて、イベント終了とともに破棄されている様子がわかります。
最近の iOS デバイスはメモリを 512 MB 以上搭載していますが、どうしてもメモリの使用量を抑えながら処理をしたい場合があるかと思います。
autorelease_pool を使ってみよう
上のコードを次のように変更します。
1 2 3 4 5 6 7 |
|
autorelease_pool
のブロックで囲むようにしただけです。Objective-C の @autorelease
ブロックと同じようですね。
Instruments.app でメモリ使用を確認してみます。
今回は一定のメモリ使用率をキープしていることが分かります。autorelease_pool
ブロックの処理が終わると、ブロック内で使用した不要なオブジェクトが破棄されていることが分かるかと思います。
autorelease_pool
を使うとメモリ使用量を抑えることができますが、メモリプールの生成とリリースがそのたびに行われるのでそのぶん処理時間が延びます。まだ作りこみが足りてないようで、autorelease_pool
で破棄されているオブジェクトにアクセスするとクラッシュするのでご注意ください。