Reputation: 43
I try to create a UIImage by filling in my own data. So far everything works fine. But if I try to call this function several times it seems to fill the memory till the App crashes. Using the VM Tracker I found out that the dirty memory grows up to 328MB whereby 290MB is CG image memory when the app crashes.
I call my function in a loop several times whereby ARC is enabled. The image is quite big but that shouldn't be a problem since it works fine for the 29 first iterations. As far as I know, dirty memory should be reused by the application again. Is that right? So why does it fill my memory and how can I avoid this problem?
for(int i = 0; i < 1000; ++i) {
UIImage *img = [self createDummyImage:CGSizeMake(2000, 1600)];
}
Function to create dummy UIImage:
- (UIImage*)createDummyImage:(CGSize)size
{
unsigned char *rawData = (unsigned char*)malloc(size.width*size.height*4);
// fill in rawData (logic to create checkerboard)
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
CGContextRef contextRef = CGBitmapContextCreate(rawData, size.width, size.height, 8, 4*size.width, colorSpaceRef, bitmapInfo);
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
CGColorSpaceRelease(colorSpaceRef);
CGContextRelease(contextRef);
free(rawData);
UIImage *image = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return image;
}
Working solution by hooleyhoop
Put function call into autorelease pool.
for (int i = 0; i < 1000; ++i) {
@autoreleasepool {
UIImage *img = [self createDummyImage:CGSizeMake(2000, 1600)];
}
}
Upvotes: 4
Views: 1745
Reputation: 9198
I think if you looked at 'live' memory in the Allocations instrument you would see that you are just running out of normal memory - nothing to do with dirty VM.
This is most likely because you have too much memory waiting to be autoreleased. Autoreleased objects won't be freed until the current autorelease pool is popped - you are trying to add hundreds of megabytes of objects to one autoreleasepool.
The answer is to manage your own autorelease pools or not do so much work in one event loop.
Sorry but i can't resist a snide comment.. In my opinion this would have been more obvious before ARC.
Upvotes: 5