On Jan 22, 2011, at 20:27, Rick Hoge wrote:

> Of course I could also just put a sleep(1); in the code after removing 
> references to the dataset objects and calling collectExhaustively, but this 
> seems pretty crude and who knows if 1 second will be long enough for some 
> ultra-large processing run (although it works just as well as a shell sleep 
> in my test runs).  
> 
> I was very close to giving up on GC, but maybe this is a vital clue.  It was 
> certainly not fun to add all the dealloc methods for my limited testing...

You *cannot* rely on GC to satisfy your timing requirements for releasing 
resources used by your application. You can't even rely rely on GC to release 
memory at all, in any deterministic sense -- its function (conceptually) is to 
make memory available when it's asked for, and *not* simply to release unused 
memory. It's certainly true that *this* garbage collector always releases 
unused memory, eventually, but the timing is unpredictable.

If your application is crashing due to running out of memory, looking at what 
happens at 'finalize' time is probably not going to get you anywhere useful. I 
think you have to start by diagnosing the problem more exactly, into one of 
these categories:

1. Too much "live" (i.e. uncollectible) data at once. This breaks down into 
three subcategories:

1a. Objects that you create, and keep strong references to, use too much memory 
in total.

1b. Your code depends on a confusion between the end of the lifetimes of your 
objects and the collection times of the memory they use. You shouldn't be 
designing with collection times in mind.

1c. Objects that are created by the frameworks internally, but which somehow 
support objects that you create (think of a cache, for example), have lifetimes 
not under your control, and remain live after your own objects' lifetimes are 
over.

(That's the scenario where I ran into a problem similar to yours -- Core Data 
has an internal cache that can't be controlled outside of the frameworks, and 
it can get very large in very strange ways. I spent months of my life trying to 
solve the resultant memory issues.)

2. You outrun the collector. Certain patterns of data usage can interact badly 
with the GC heuristics. Submitting a bug report is a good idea, because Apple 
likes to find the edge cases. That likely won't help with finding an immediate 
solution, of course.

3. There's bug in the collector. Not likely, but possible.

If you've designed your application carefully, then problem 1a likely means you 
have a bug somewhere in your code. Problem 1b is an application design flaw. 
All the other problems (1c-3) basically suck, because you're dealing with 
behavior outside your control.

Switching to a retain/release pattern is unlikely to help. It has the 
essentially the same limitations as GC with regard to resource releasing, 
though you can get away with Doing It Wrong more often.

I don't want to sound too discouraging here. My suggestion is to put the 
collection timing (and finalize) out of your mind, and concentrate on the 
crashes instead. At that moment, you want to know not what's pending 
collection, but what's live. As others have already mentioned, you have some 
good tools available to you -- Instruments for memory usage, and 'info 
gc-roots' for tracking down strong references.


_______________________________________________

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