0

私はこの問題の解決策を見つけるためにあらゆる場所を探してきました。何も役に立たないようです。

メモリが解放されない理由を見つけるために、この基本的なテストを設定しました。

if (texture != nil)
{
[texture release];
texture = nil;
}
else
{
UIImage* ui = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"]];
texture = [[Texture2D alloc] initWithImage:ui];
}

ここで、これをタッチ開始に配置し、最初のタッチ後、開始時に計測器 (通常は 11.5 - 12mb) を使用してメモリ使用量を監視することでテストします。オブジェクトが存在しない状態で、テクスチャが作成され、メモリが 13.5 - 14 にジャンプします。

ただし、2 回目のタッチの後、メモリは減少しますが、約 12.5 ~ 13 に過ぎません。

まだかなりの量のメモリが占​​有されています。

これをはるかに大規模にテストし、これらの大きなテクスチャを一度に 10 個ロードしました。メモリは 30 MB を超えてそこにとどまりますが、テクスチャを解放した後の 2 回目のタッチでは、約 22 MB にしか落ちません。

[uiimage imagenamed:] を使用してイメージをロードするテストをもう一度試しましたが、このメソッドが実行するキャッシングのために、30MB が完全にメモリに残っていることを意味します。

4

2 に答える 2

0

テクスチャの割り当てを解除できるコード内の場所は 1 つだけです (ご覧のとおり)。それは[texture release];ステートメントにあります。

そのステートメント(または別のステートメント)を実行する必要があります。割り当てたすべてのテクスチャに対して、それを解放することも確認しましたか? 次のように、NSLog ステートメントを追加して支援できます。

if (texture != nil) {
    NSLog("releasing texture instance: %08x", texture);
    [texture release];
    texture = nil;
} else {
    ...
    texture = [[Texture2D alloc] initWithImage:ui];
    NSLog("allocated texture instance: %08x", texture);
}

おそらく、テクスチャは別の場所に保持されていますか?たとえば、サブビューに追加するか、配列または辞書に追加しますか? それらは内容を保持します。

最後の手段として、本当に困難な alloc/release 追跡の問題に対して、retain、release、dealloc メソッドをオーバーライドして、予期したときに呼び出されることを確認しました。この時点ではやり過ぎかもしれませんが、その方法は次のとおりですint myRetainCount;。追跡するのに役立つ ivar を追加しました。

-(void)release {
    NSLog(@"release %08x %2d -> %2d (%u)", 
          self, myRetainCount, myRetainCount-1, self.retainCount);
    myRetainCount--;
    [super release];
}

-(id)retain {
    NSLog(@"retain  %08x %2d -> %2d (%u)", 
          self, myRetainCount, myRetainCount+1, self.retainCount);
    myRetainCount++;
    return [super retain];
}

- (void)dealloc {
    NSLog(@"dealloc %08x %2d       (%u)", self, myRetainCount, self.retainCount);

    // deallocate self's ivars here...

    [super dealloc];
}
于 2010-05-04T03:32:49.433 に答える
0

私は問題を見つけたようです。なぜそれが起こるのかよくわかりませんが、メモリ使用量を監視するために計測器を実行すると、同時に I/O アクティビティを監視している場合 (これは最初にロードされたデフォルトの計測器です)、示されたメモリ使用量は非常に大きく (3 倍以上)、オブジェクトの割り当てが解除された後もメモリに残ります。これは、I/O アクティビティを監視するオーバーヘッドが原因だと思います。

とにかく、これをオフにすると、メモリ使用量は最初に 3.16mb (はるかに良い) で報告され、10 個の巨大なテクスチャをロードすると 10mb にジャンプし、テクスチャをアンロードするとすぐに 3.16 に戻ります。素晴らしい結果です。

于 2010-05-04T23:22:06.787 に答える