> 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 protected]) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [email protected]
