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: Quincey Morris <email@hidden>
- Date: Sat, 22 Jan 2011 21:28:50 -0800
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 (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