From: Matthew Bloch Date: 2002-05-23T00:00:23+09:00 Subject: Stymied by Ruby's garbage collector Hello; This one is driving me crazy: I've got an about-to-be-deployed entertainment product written in Ruby using SDL for the graphics (through RUDL), and I've hit a brick wall with what I believe is the garbage collector. Basically, the drawing loop for a particular screen takes the same time every frame but occasionally the garbage collector kicks in and makes the whole game lurch for that frame: graphics jump to compensate etc. and this is a regular occurrence (once every 2/3 secs). I've tried turning it off during critical sections of animation, but on most systems I've tried, it gobbles all the memory before Ruby can start garbage collection again. I know the problem *is* down to the garbage collector's timing because I can see smooth animation for a few seconds after GC.disable (where there wasn't before) before the inevitable seizure. Looking at Ruby's garbage collector (from 1.6.7), it seems an 'all-or-nothing' proposition. That is, the whole algorithm is run at any point to free as much memory as possible, or it is not. There's no partial collection to satisfy what may be a small allocation request. Now my deadline is pretty tight on this, so I'm after some tips to solve this in the short term for now :-) Various solutions present themselves, in order of simplicity: *) Upgrade the game's runtime to Ruby 1.7 -- does this have a less lumpy gc algorithm? Or is there an even more advanced version of Ruby around from which I could steal just a better gc? *) Redesign critical parts of the game to stop burning through so much damned memory-- but surely this would ruin the maintainability of the code, to have to scope everything as widely as possible? Or are there other techniques I can use for the same end? *) Hack the gc algorithm used by ruby_xmalloc etc. to stop recovering memory after the number of bytes needed is available, rather than running the whole algorithm. I haven't studied the algorith in detail yet, so I have no idea whether this is viable; *) Find the correct places to GC.disable / GC.enable to smooth the more visible glitches over-- but I'd be very wary to deploy such a solution because it's unpredictable across different systems and in the worst case can seize the machine up totally. *) last resort: leave everything as it is, but deliberately slow animation loops to assume the worst case. Can anyone who's been in a similar situation comment? I assume this kind of problem is endemic to games that rely on garbage collectors, so someone must have some opinions :-) thanks in advance, -- Matthew