[iPhone] Determinisic autorelease pool drain?

I know that an autorelease pool is said to drain at the end of the run loop. But how can you know/force that to happen during the call stack execution?

For example during image processing, one needs to do a memory intensive operation, followed immediately by another - but must free all memory from the first operation beforehand.

One idea I had is using timer/notifications between every step, but I'm not sure that guarantees anything.

MBP, Mac OS X (10.5.8)

Posted on Oct 15, 2010 1:32 PM

Reply
10 replies

Oct 18, 2010 2:42 PM in response to etresoft

Right but let me make a more specific example-


for(int i=0;i<1000;i++)
{
d=[self dataManipulatingMethod:d]; //Allocates a lot of autoreleased objects
}


I need to run through that loop as many times as I want, but nothing I do seems to allow that to happen without burning all the memory. I tried the following, which I feel like should work:



for(int i=0;i<1000;i++)
{
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
d=[[self dataManipulatingMethod:d] retain]; //Allocates a lot of autoreleased object
[pool drain];
}


.. but I still burn out all the memory on the device. The dataManipulatingMethod specifically releases or autoreleases everything it creates.

Oct 18, 2010 4:26 PM in response to sptrakesh

Does creating and destroying the pool from within dataManipulatingMethod show the same behaviour?



Yes it does... But, I'm wondering if its not so much an autorelease bug as it is a problem with the image data I'm dealing with.. Seems like a bug in the CGContext stuff or something.. Here's the actual method:


+(UIImage)testMethod:(UIImage)img
{


NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
float w=img.size.width;
float h=img.size.height;
CGRect imgRec=CGRectMake(0, 0, w, h);


UIGraphicsBeginImageContextWithOptions(img.size ,YES, 1.0); //Create a context (freed below)

CGContextRef ctxt = UIGraphicsGetCurrentContext(); //Get reference to the context

[img drawInRect:imgRec]; //Draw existing image into context

UIImage *resultImg=UIGraphicsGetImageFromCurrentImageContext(); //This is autoreleased according to UIKit docs

[resultImg retain]; //Retain this image since we will drain the pool



UIGraphicsEndImageContext(); //Destroy the context we created earlier

//CGContextRelease(ctxt); // Crashes if we try to also explicitely release the context.. So it must be deallocing with above line.

[pool drain];

[resultImg autorelease];

return resultImg;



}

Oct 18, 2010 7:58 PM in response to etresoft

I'm creating the pool to ensure that whatever UIGraphicsGetImageFromCurrentImageContext does behind the scenes is freed when I want it to be.

Also other CG functions might be creating autorelease objects and the only way I can guarantee that they will be gone when this method is complete, is to create my own pool.

(Also this method I posted is a stripped down version of the real thing, but still shows the odd behavior)

Oct 18, 2010 8:58 PM in response to sptrakesh

Where does the d instance get released?


Ahh, hmm. It was being released down the page somewhere, but as it turns out I didn't need that retain at all. Good catch. But that wasn't enough, I also need to dealloc the incoming image when I'm done with it. So I threw a release in the image processing method:


+(UIImage)testMethod:(UIImage)img
{


NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
float w=img.size.width;
float h=img.size.height;
CGRect imgRec=CGRectMake(0, 0, w, h);


UIGraphicsBeginImageContextWithOptions(img.size ,YES, 1.0); //Create a context (freed below)

//CGContextRef ctxt = UIGraphicsGetCurrentContext(); //Get reference to the context

[img drawInRect:imgRec]; //Draw existing image into context

[img release]; //<<<<---- ADDED THIS RELEASE.. BUT THIS ISN'T GOOD PRACTICE?

UIImage *resultImg=UIGraphicsGetImageFromCurrentImageContext(); //This is autoreleased according to UIKit docs

[resultImg retain]; //Retain this image since we will drain the pool



UIGraphicsEndImageContext(); //Destroy the context we created earlier

//CGContextRelease(ctxt); // Crashes if we try to also explicitely release the context.. So it must be deallocing with above line.

[pool drain];

[resultImg autorelease];

return resultImg;



}

I don't believe this is good form because the method is releasing something it didn't retain/create. But I don't see how else to do it where I can control exactly when the "incoming" image is released.. Autoreleasing from the 'higher' level won't do it..

Oct 19, 2010 8:22 AM in response to typewriter

typewriter wrote:
I'm creating the pool to ensure that whatever UIGraphicsGetImageFromCurrentImageContext does behind the scenes is freed when I want it to be.


I doubt there is any "behind the scenes" allocation going on. Apple knows how much RAM the device has. They aren't going to allocate a bunch of objects and hope that your autorelease pool is properly structured. They are returning an autoreleased object because that is how they have defined such things to work.

In this case, the big autoreleased object that is being returned is not going on your new autorelease pool.

Also other CG functions might be creating autorelease objects and the only way I can guarantee that they will be gone when this method is complete, is to create my own pool.


The architecture is designed so that you shouldn't have to worry about this. The system autorelease pool is drained each time an event is serviced from the run loop. You only need to have your own autorelease pool if you have your own threads or allocating lots of memory and you need more fine-grained control.

I think you are just allocating too much memory and holding onto it longer than you need to. It isn't an autorelease issue but a memory management issue.

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

[iPhone] Determinisic autorelease pool drain?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.