【问题标题】:Im Stumped, Why is UIImage\Texture2d memory not being freed我被难住了,为什么 UIImage\Texture2d 内存没有被释放
【发布时间】:2011-02-15 06:49:57
【问题描述】:

我一直在寻找解决这个问题的方法。似乎没有任何帮助。

我设置了这个基本测试,试图找出我的内存没有被释放的原因:

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

但是,在第二次触摸后,内存确实会减少,但只会下降到 12.5 - 13 左右。

仍有一大块内存被占用。

我在更大的范围内对此进行了测试,一次加载 10 个这样的大纹理 内存跃升到超过 30 mb 并保持在那里,但在释放纹理后的第二次触摸时,它仅下降到 22 mb 左右。

我再次尝试使用 [uiimage imagenamed:] 加载图像时进行测试,但由于此方法执行缓存,这意味着整个 30mb 仍保留在内存中。

【问题讨论】:

    标签: iphone uiimage memory-management texture2d


    【解决方案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);
    }
    

    也许纹理被保留在其他地方?例如,您是否将其添加到子视图或数组或字典?那些保留其内容。

    作为最后的手段,对于真正棘手的分配/释放跟踪问题,我重写了保留、释放、释放方法,以验证它们是否在我期望的时候被调用。在这一点上这可能有点矫枉过正,但方法如下:我添加了一个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];
    }
    

    【讨论】:

    • 感谢您的宝贵时间,以及如此快速的回复:)。为了这个测试,这个纹理被引用的唯一地方(除了在接口声明中)是在我发布的代码中。我迫切需要一个解释,我可能会尝试你建议的那些覆盖。但是我认为问题一定是我不知道的其他问题。也许某些特定于 Texture2D 或 iPhone 处理内存的方式,或仪器本身。使用调试器,我已经证明了 texture2d 的 dealloc 方法已被调用。
    【解决方案2】:

    看来我找到了问题所在。我不太清楚为什么会发生这种情况,但是当我运行仪器来监控内存使用情况时,如果我同时监控 I/O 活动(这是最初加载的默认仪器),似乎显示的内存使用量要大得多(超过 3 倍),即使在对象被释放后仍保留在内存中。我认为这是因为监视 I/O 活动的开销。

    无论如何,当我关闭它时,内存使用量最初报告为 3.16mb(好多了),并在加载 10 个巨大的纹理时跳转到 10mb,并在我卸载纹理后立即回到 3.16。一个辉煌的结果。

    【讨论】:

      猜你喜欢
      • 2013-05-24
      • 2021-10-03
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      相关资源
      最近更新 更多