修正日: 07/10/23
MallocDebug
Performance Tools入門 その1
5. メモリリークを検出する
All Allocationsポップアップボタンで「Leaks」を選択することで、リークしたと考えられるメモリブロックを一覧表示できます。(1) 試してみる
サンプル「mLeaker」をMallocDebugで起動し一番上の「String Leak」ボタンを押してください。
を5万回呼び出しています。このブロックはすべてリークします。処理が終わったらMallocDebugでLeaksを選択し、NSString initWithFormat:で5万個近いメモリブロックがリークしていることを確認しましょう(図10)。(かならずしも5万にはなりません)
[[NSString alloc] initWithFormat:@"This is test string No.%d!!",i];
を5万回呼び出しています。このブロックはすべてリークします。処理が終わったらMallocDebugでLeaksを選択し、NSString initWithFormat:で5万個近いメモリブロックがリークしていることを確認しましょう(図10)。(かならずしも5万にはなりません)
【図10】 String Leakのリーク検出結果
![](images/malloc/10.png)
(2)メモリリーク検出の方法
MallocDebugではメモリ内に存在する全てのポインタをリストアップし、どのポインタからも参照されていないメモリブロック/オブジェクトをリークと見なします。
(3)メモリリーク検出の限界
メモリブロックを参照しているポインタが一つでもあれば、そのメモリはリークとは認識されません。従って以下のようなタイプのメモリはリークとして検出されないので注意しましょう。
- 相互に参照しているオブジェクト
- 循環的に参照しているオブジェクト
- ツリー構造になっているオブジェクトでルート以外のオブジェクト
(4)リーク検出の範囲を試してみる
リーク検出の限界を試してみます。サンプル「mLeaker」をMallocDebugで起動し、「Array Leak」ボタンを押してください。
leakedArrayという配列に5万個のNSStringをaddしArrayごとリークさせます。終わったらMallocDebugでリークを検出してみましょう。NSArray1つのリークしか検出できないはずです
(図11)。
【図11】Arrayリークのリーク検出結果
![](images/malloc/11.png)
配列内のNSStringオブジェクトはNSArrayから参照されているためリークとは見なされないためです( (3)-3参照)。リーク量が少ないからといって油断すると思わぬ問題を見落とす可能性がありますので注意しましょう。
NSMutableArray *leakedArray;
leakedArray=[[NSMutableArray arrayWithCapacity:50000] retain];
int i;
for(i=0;i<50000;++i)
[leakedArray addObject:
[[NSString alloc] initWithFormat:@"This is test string No.%d!!",i]];
leakedArrayという配列に5万個のNSStringをaddしArrayごとリークさせます。終わったらMallocDebugでリークを検出してみましょう。NSArray1つのリークしか検出できないはずです
(図11)。
【図11】Arrayリークのリーク検出結果
![](images/malloc/11.png)
配列内のNSStringオブジェクトはNSArrayから参照されているためリークとは見なされないためです( (3)-3参照)。リーク量が少ないからといって油断すると思わぬ問題を見落とす可能性がありますので注意しましょう。