I have an application based on the "Cocoa Application" template in Xcode 
(x86_64, currently testing on OSX 10.6.5) that listens for client messages 
using an NSConnection.  Both client and server have been designed for garbage 
collection, and are compiled GC-only.  The client is a simple command-line 
program that uses 

[NSConnection rootProxyForConnectionWithRegisteredName:serverName host:nil];

to send it's messages to the server.  The messages direct the server to load 
large-ish data files (200MB) and perform processing on them.  Periodically the 
client may direct the server to unload all of the large datasets from memory, 
which the server does by calling the 'removeAllObjects' method of a mutable 
array that holds the list of all loaded datasets.  Under real conditions, we 
would expect to load around five of these datasets at a time, perform 
processing, unload, and then load another five.  

I have overridden the 'finalize' method of the dataset class to print a log 
message before calling [super finalize], and when I perform a single processing 
'run' in which the client sends a message to the server directing it to load a 
200MB dataset and then perform a series of processing operations which result 
in five datasets being open, I have noticed that - while the finalize methods 
are indeed called - they are called around five to ten seconds after the last 
processing directive is sent from the client.

For five datasets the above behaviour is not a problem, but in more realistic 
tests where we generate five datasets, flush, then generate five more, before 
repeating the cycle perhaps 10 times, the finalize methods never appear to be 
called (or at least no log messages appear).  The memory usage becomes huge, 
and eventually the program crashes.

In these runs, a shell script repeatedly invokes the client program to send 
messages to the server program.  The server (which has a UI) might spend all 
it's time in an 'inactive' state with no user input.  The commands are 
currently run on the main thread of the server.  However the memory 
accumulation and crash happen whether or not I click on the server window to 
bring it to the foreground.

I'm pretty sure I'm not leaking the memory with an unintended reference, as the 
datasets *are* collected (albeit not very quickly) after I run a set of five 
operations and the server returns to be waiting for user input.  I'm wondering 
if it could be because collection will not happen until the end of a run loop, 
and by bombarding the server with messages then collection is never triggered 
because it never senses the end of the run loop.  I gather that there may be 
special considerations with runloops and NSConnection.

Note that I *am* calling collectExhaustively right after the various stages in 
the server when data should be flushed, but this does not seem to help.  I do 
the call at the end of the method in which client messages are processed - is 
it possible this should be run using performSelector after the current run loop?

I'm at the point where I am reconsidering whether GC is really appropriate for 
this application, but also think I may well be doing something silly that can 
easily be fixed.

Would be grateful for any suggestions!

Rick





_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to