12 March, 2007

Weekend Followup

I've been getting a lot of emails about my last post, particularly in regards to Dolphin's garbage collection (some of them generalized this to Smalltalk, which would be wrong), and some regarding garbage collection in games period. Instead of answering each of them or replying to blog comments in a comment, I decided to follow-up with another post....

In a garbage collected language, collection times are a reality. A 30 ms spike isn't horrible (I cringed as I typed that) as long as it's only once every 10-15 minutes. Right now, the collections are occurring roughly every couple minutes. This is unacceptable.

The only real choices are to either turn the collector off and force collections at known "good" times (which for some games isn't an option), write code in a manner that severely limits how often they are needed, or a combination of both. Either way, eventually the memory manager will need to sweep over a large set of objects and see what can be collected. And, while optimizations can be made, this is a problem that will always exist.

Turning off the collector isn't really an option [for me]. I can't make that generalization for all games created with the engine, and I can't generalize when a collection should happen. An individual game can choose to do this, but I won't be forcing that down anyone's throat. But, I do need to reduce how often a collection is needed. This will require special collection classes (pools), some intimate knowledge of the VM, and a certain amount of black-box trust. Sadly, "black-box trust" is something I keep in short supply these days.

Currently, I don't think lots of particles are causing the majority of the GC's - they're just shining a bright light on the real problem(s). My gut tells me that it's the VM not properly handling short-lived objects well. Particle updating currently uses a lot of Point objects for temporary calculations. The compiler probably doesn't recognize that they can't possibly be referenced outside the scope of the method, and therefore doesn't optimize their creation and deletion.

I need to ping Object Arts before making too many assumptions about the internals, though. I don't know if Dolphin uses mark and sweep, multi-generational garbage collection, simple reference counting, something else, or a combination approach. I could be pretty far off base. Be assured I will post a very detailed analysis of my findings and what I'm doing to take care of the problem.

1 comment:

Flatlander said...

It certainly sounds like the problem is the GC inability to cope with lots of short lived objects. There are all kinds of GCs with different performance profiles and the (possible...) problems shouldn't be over generalized.

I believe that with a decent generational GC there shouldn't be any problem, I have run some of my GCed games with age old PIIs and there never was any GC related issues.

Or maybe the Dolphins FFI adds some overhead, it's quite possible that it never was designed to be used like this. For example, some years ago I had GC problems with CMUCL and it turned out that for some reason even calling a foreign function like 'void foo(void)' repeatedly allocated ridiculous amounts of memory.

Hope you got it sorted out :)