Re: Problem with garbage collection in server application
Re: Problem with garbage collection in server application
- Subject: Re: Problem with garbage collection in server application
- From: Dave Keck <email@hidden>
- Date: Sun, 23 Jan 2011 00:59:29 -0500
> I worked up a version of our app that uses retain/release style memory management, and was surprised to note that a similar thing was happening (although the memory use did not get as big). Running a script that would send five sequential processing requests to the server, with a 'close all' at the end, would result in immediate deallocation of all five datasets. However if I put the script commands inside a for loop (scripted to repeat two or more times), then the datasets are not deallocated until the end of all loops. I put a breakpoint on 'retain' in my dataset objects, and it's clear that they are getting a lot of retains from various observer objects in the user interface used to monitor script execution. The UI objects must be getting dealloc'ed themselves, as the dataset objects are eventually released.
The autorelease pool is popped after the current iteration of the run
loop exits. If the datasets are autoreleased explicitly by you, or
implicitly by any number of APIs that you call, then indeed the
objects won't be deallocated until the run loop iteration exits. If
you need (more) determinate behavior over your datasets' deallocation,
surrounding your loop with its own autorelease pool is probably the
solution. It doesn't sound like that solution would translate to your
production code, though.
> I noticed that if I put a 'sleep 1' at the bottom of the loop in my shell script, then the dataset objects would indeed be deallocated at the bottom of the loop (not after all loops). So it might be that all the KVO stuff for the UI is getting cleaned up very late in the run loop, in a process that is interrupted by another message to the NSConnection immediately upon exit.
>
> After seeing this in the retain/release version, I then tried running the GC version with the 'sleep 1' at the bottom of the loop. Lo and behold, the objects were getting finalized at the bottom of each loop (slightly asynchronously from the main thread, but that's fine). A number of tests also showed that the GC version ran around 10% faster for long processing runs.
>
> So maybe all this is a symptom of an uncontrolled interaction between the NSConnection I use to run client requests, and the NSRunLoop that is associated with the UI.
I'm sure bbum will correct me where I'm wrong, but my understanding is
that the collector, running in its own thread, can and does perform
its collections asynchronously with respect to other threads. While it
takes hints as to when a collection is necessary (such as when memory
has passed a high-water mark), I've never heard that collections are
timed with respect to any thread's run loop.
> Perhaps I should be looking for some way to force the app to wait until the end of the current runloop before accepting another message on the NSConnection, but I'm not sure how to do that.
Beyond removing strong references to your datasets and verifying that
they're gone (via info gc-roots), I wouldn't put much more effort into
getting GC working as you'll quickly defeat the purpose. On the other
hand, if I understood you correctly in that you're seeing a 10%
speedup when using GC, then perhaps that would warrant the extra
effort. On the other-other-hand, it sounds like you might be
optimizing early.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden