第7回 メモリ管理を理解する(前編)
竹下 肯己
株式会社 qnote
2009/7/23
iPhone用アプリケーション開発で注目を集める言語「Objective-C」。C++とは異なるC言語の拡張を目指したこの言語の基本を理解しよう(編集部)
- - PR -
あらゆるアプリケーションは、システムのメモリ上に展開されて動作します。
メモリは限られた資源なので、アプリケーションは資源を無駄に消費しないよう自己管理しながら動作する必要があります。この動作を実現するのが、開発者によるメモリ管理の実装です。
新しく登場した言語のなかにはメモリ管理が自動で行われる(言語のエンジン部分で暗黙的にメモリ管理がされている)ものが多いため、開発者がメモリ管理を意識することが少なくなっています。
実際、Objective-Cでも、Objective-C 2.0から(Mac OS X 10.5 から)はガベージコレクションという自動メモリ管理の仕組みが導入されています。
しかし、自動でのメモリ管理は、すべてのアプリケーションにおいて必ずしも効率的であるとは限りません。よりシビアにメモリ管理を行う必要があるアプリケーションでは、開発者が場面に応じて明示的にメモリの割り当てや解放を行うことで、スマートでパフォーマンスに優れたプログラムを作ることができます。
そもそもガベージコレクションが利用できないプラットフォーム(Mac OS X 10.4 以前や、iPhoneなど)のことも考慮しなければなりません。
連載の最後の2回を使って、Objective-Cにおけるメモリ管理の基本的な仕組みについて解説したいと思います。
オブジェクトがどれだけ必要とされているか
メモリ管理とは具体的に何を行っているのでしょうか。それは、必要なときにプログラムのデータをメモリ上に展開(メモリ領域を割り当て)し、必要がなくなったら、そのメモリ領域を解放することです。
管理の対象となるデータは、オブジェクト指向の言語では、多くの場合クラスのインスタンスです。クラスインスタンスの生成(メモリ割り当て)が必要になるタイミングについては、あまり迷うことはないでしょう。問題は、それをいつ解放するかです。
インスタンスを生成する側の閉じた文脈のなかでは、インスタンスの要不要は比較的簡単に判断できるかもしれません。しかし、これまでも見てきたように、生成したインスタンスは、メソッドを介して別のオブジェクトに渡される場合があります。渡した先の文脈で、そのインスタンスがいつまで必要とされるのか、不要になったらちゃんと解放してくれるのか、といったことは知る由もありません。
このような問題に対処するため、Objective-Cでは、あるオブジェクトがどれだけ必要とされているか(あるいは不要と判断されたか)を、単純にプラスマイナスでカウントしていく仕組みを採用しています。この仕組みを参照カウンタといいます。
例えば、プログラムロジックのある場所で「このオブジェクト、ちょっとしばらく使うから、破棄(メモリの解放)しないでね」という宣言をしておきます。すると、参照カウンタは1プラスされます。
その後、「さっき必要っていったけど、使い終わったから少なくとも僕のところではもう要らないよ」といった宣言をします。すると、参照カウンタは1マイナスされます。
このような、オブジェクト所有権の獲得と放棄(参照カウンタの増減)を、文脈ごとに自分の守備範囲内で行います。別のオブジェクトに渡してしまったら、そちらでどう扱われるかは守備範囲外となりますので関知しません。
参照カウンタが0になると、そのオブジェクトは誰も必要としていないということになるので、そのメモリ領域は解放されます。
参照カウンタの動きを見てみよう
「このオブジェクトを消さないで!」の宣言にはretainというメソッドを、「もう要らなくなったよ!」という宣言にはreleaseというメソッドを利用します。どちらもNSObjectのメソッドなので、あらゆるクラスのオブジェクトから呼び出すことができます。
まず、参照カウンタの増減を簡単なサンプルで確認してみましょう。あるオブジェクトの参照カウンタの値は、retainCountというメソッドで取得できます。
01 #import <Foundation/Foundation.h>
02
03 int main(void) {
04
05 NSObject *myObj = [[NSObject alloc] init]; // (a)
06 printf("%d\n", [myObj retainCount]); //
07
08 [myObj retain]; // (b)
09 printf("%d\n", [myObj retainCount]); //
10
11 [myObj release]; // (c)
12 printf("%d\n", [myObj retainCount]); //
13
14 [myObj release]; // (d)
15 //printf("%d\n", [myObj retainCount]); // (e)
16
17 return 0;
18 }a. インスタンスを生成した時点(allocメソッドを実行した時点)で、参照カウンタは1になります。
b. retainメソッドで参照カウンタを1プラスします。この時点で参照カウンタは2になります。
c. releaseメソッドで参照カウンタを1マイナスします。この時点で参照カウンタは1になります。
d. さらにreleaseメソッドを呼び出して、参照カウンタをマイナスします。この時点で参照カウンタは0になり、オブジェクトは解放されます。
e. すでに解放されているので、このオブジェクトにアクセスできません。サンプルコード中のコメントを外すとエラーになります。
1/2 |
| Index | |
| メモリ管理を理解する(前編) | |
| Page1 オブジェクトがどれだけ必要とされているか 参照カウンタの動きを見てみよう |
|
| Page2 クラスのインスタンス変数の所有権 クラスのインスタンス変数の解放 |
|
| Cocoaの素、Objective-Cを知ろう |
| Mac OS X関連記事 |
| プログラマーを引き付けるMac OS Xの魅力 続々移行するそのワケとは Mac一筋という熱狂的なユーザーだけでなく、「面白いことをしたい」と考えるエンジニアもMac OS Xを利用し始めている。いったいなぜだろう |
|
| Mac OS XでAMP構築 3通りの方法で整備できる開発環境 Mac OS Xの上にWebアプリケーションの定番、AMP(Apache+MySQL+PHP)環境を3通りの方法で導入してみましょう |
|
| Mac OS Xで動かす軽量プログラミング言語 導入からPHP拡張モジュール組み込みまで Leopardでは、インストール直後からいくつかの軽量プログラミング言語が利用できます。早速試してみませんか? |
|
| Objective-Cは特殊な言語? Cocoaの素、Objective-Cを知ろう(1) iPhone用アプリケーション開発で注目を集める言語「Objective-C」。C++とは異なるC言語の拡張を目指したこの言語の基本を理解しよう |
|
| Mac内にPHP4、5、6を同居させるコツ Mac OS X+PHPでオールインワン環境(インストール編) PHP4の開発は終了したが、移行の問題は残されている。異なるバージョンのPHPをスムーズに切り替えるには? |
|
TechTargetジャパン
- 実例で学ぶRailsアプリのテスト方法 (2011/12/22)
具体的なWebアプリを例に簡単なテストを使ったリファクタリングについ
て解説する - Railsの人気テストフレームワーク6選! (2011/8/18)
今回からテストを使ったリファクタリングを解説する。まずはRailsで人
気のあるテストフレームワークをいくつか紹介する - ActiveRecordの更新系操作 (2011/6/27)
Railsのモデル層を担当するActiveRecordを使った登録、更新、削除
など、更新系の機能を中心に見ていきます - 実例アプリで学ぶ“Railsらしさ”の基礎 (2011/5/26)
Ruby on Railsで書かれた実例アプリを取り上げて、初心者が陥りがちなコードの書き方を指摘します。より「Railsらしい」コードとは?
|
|

