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 = [[开发者_C百科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.
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];
}
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.
精彩评论