我很困惑,为什么 UIImage\Texture2d 内存没有被释放

发布于 2024-08-31 04:39:54 字数 669 浏览 4 评论 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。

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

仍有明显的内存块被占用。

我在更大的规模上进行了测试,一次加载 10 个这样的大纹理 内存跳至超过 30 mb 并保持不变,但在释放纹理后第二次触摸时,内存仅降至 22 mb 左右。

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

I've been looking everywhere trying to find a solution to this problem. Nothing seems to help.

I've set up this basic test to try to find the cause of why my memory wasn't being freed up:

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

Now i would place this in the touches began and test by monitoring the memory usage using intstruments at the start (normally 11.5 - 12mb)
after the first touch, with no object existing the texture is created and memory jumps to 13.5 - 14

However, after the second touch the memory does decrease, but only to around 12.5 - 13.

There is a noticeable chunk of memory still occupied.

I tested this on a much larger scale, loading 10 of these large textures at a time
The memory jumps to over 30 mb and remains there, but on the second touch after releasing the textures it only falls to around 22mb.

I tried the test another time loading the images in with [uiimage imagenamed:] but because of the caching this method performs it just means that the full 30mb remains in memory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独患者 2024-09-07 04:39:54

代码中只有一处(从我们所见)可以释放纹理,那就是 [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];
}

There's only one place in your code (from what we can see) where texture can be deallocated and that's at the [texture release]; statement.

You need to be executing that statement (or another one somewhere else). Did you verify that for every texture you alloc that you also free it? You can add NSLog statements to help, like so:

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);
}

Perhaps texture is being retained somewhere else? For example, do you add it to a subview or to an array or a dictionary? Those retain their contents.

As a last resort, for really tough alloc/release tracking problem, I've overridden the retain, release, dealloc methods to verify that they are called when I expect. This might be overkill at this point, but here's how: I added an int myRetainCount; ivar to help me keep track:

-(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];
}
芸娘子的小脾气 2024-09-07 04:39:54

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

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

It seems i have found the problem. I don't quite know why it happens, but it seems when i run the instruments to monitor the memory usage, if i am monitoring the I/O activity at the same time (which is the default instrument that is initially loaded in) the memory usage showed is A LOT larger (over 3 times larger) and remains in memory even after the objects are dealloc'd. I assume this is because of the overhead of monitoring I/O activity.

Anyway, when i turn this off the memory usage initially reports at 3.16mb (a lot better) and jumps to 10mb when loading the 10 huge textures and goes right back down to 3.16 after i unload the texture. A brilliant result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文