InternalTimerThread and autorelease pool


#1

Hey Julian, using the tip…

So i’ve just been doing some profiling and noticed in Instruments that I had a bunch of NSConcreteData’s being allocated and not released.

I notice in mac_threads.mm

void* threadEntryProc (void* userData) throw() { const ScopedAutoReleasePool pool; juce_threadEntryPoint (userData); return 0; }

Which takes care of creating an autorelease pool for a thread…but in the case of Juce’s Internal Timer it doesn’t drain until the app is quit.(About 100 bytes a second)

The issue seems to be

in juce_Timer.cpp

postMessage (new Message());

Which eventually calls down into mac_MessageManager and juce_postMessageToSystemQueue which allocates an autoreleased NSData, which is retained once and released once by the OS when delivered. Which means its now sitting in the autorelease pool.

So I suppose you could add some sort of drain method in Timer just before postMessage that creates and releases an NSAutoReleasePool for the postMessage…

or…this may be more efficient…

(use alloc/init in the postMessageToSystemQueue and balance it with a release in the customEvent)

[code]
bool juce_postMessageToSystemQueue (void* message)
{
atomicIncrement (numPendingMessages);

[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:)
                 withObject: (id) [[NSData alloc]initWithBytes:&message length:(int) sizeof (message)]
                 waitUntilDone: NO];

return true;

}[/code]

- (void) customEvent: (id) n
{
    atomicDecrement (numPendingMessages);

    NSData* data = (NSData*) n;
    void* message = 0;
    [data getBytes: &message length: sizeof (message)];
	[data release];
	
    if (message != 0 && ! flushingMessages)
        redirector->deliverMessage (message);
}

Hope that helps

Justin


#2

Here’s the “before”- (32 bytes every 100 ms or so)


#3

Damn - you’re right. Thanks very much, I’ll get a fix in for that…