Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to periodically drain the autorelease pool on a long-running background thread?

In the developer documentation, it says:

If your application or thread is long-lived and potentially generates a lot of autoreleased objects, you should periodically drain and create autorelease pools (like the Application Kit does on the main thread); otherwise, autoreleased objects accumulate and your memory footprint grows. If, however, your detached thread does not make Cocoa calls, you do not need to create an autorelease pool.

I was wondering what the best way to do this is. I have several methods I think would work, but don't know which is the "best". I currently have a method that start the thread and keeps it waiting for operations to perform:

- (void)startThread
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    accessoryRunLoop = [NSRunLoop currentRunLoop];

    //Add a dummy port to avoid exiting the thread due to no ports being found
    [accessoryRunLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

    while(accessoryThreadIsRunning)
    {
        //Keep the thread running until accessoryTheadIsRunning == NO
        [accessoryRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }

    [pool release];
}

My options I can think of are:

1) Add a counter in the while(accessoryThreadIsRunning) so that every 50 or 100 times it will drain the autorelease pool and create a new one.

2) Every time I perform a method in that thread (using performSelector: onThread:), I can create an autorelease pool and then release it at the end of the method.

3) Make a timer so that a pool is drained and then created periodically.

I think that option 1 is the best, but would like to know if there is a different way I should be doing this. Thanks!

like image 610
Ned Avatar asked Sep 27 '10 19:09

Ned


People also ask

How autorelease pool is managed?

Overview. An autorelease pool stores objects that are sent a release message when the pool itself is drained. If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks.

Are Autorelease pools thread safe?

@John - You shouldn't remove the autorelease pool. Create it within the thread so that it can manage autoreleased objects, but anything you wish to hang around after the thread has finished executing should be manually retained (and later manually released), or initialized using -init or copy .

What is Autorelease pool in Swift?

The autoreleasepool allows you to explicitly manage when autorelease objects are deallocated in Swift, just like you were able to in Objective-C. Note: When dealing with Swift native objects, you generally will not receive autorelease objects.


1 Answers

I'd start with dead simple and just create/drain the pool on every pass through the loop.

If it shows up during performance analysis as a bottle neck, fix it.

Keep it simple until analysis indicates complexity is required.


I just re-read your question and realized something entirely boneheaded in my answer. If you are running a run-loop it should be managing an autorelease pool automatically for you; it should create a pool at the top of the loop and drain it at the end of each pass through the loop.

You only need to cycle one yourself if you have other stuff going on outside of the runloop. Is that the case?

In any case, yes, the pattern is:

 while(...) {
    ... create pool ...
    ... do stuff ...
    ... drain pool ...
 }
like image 53
bbum Avatar answered Sep 19 '22 01:09

bbum