Ruby's garbage collector is garbage. There are many tips online
for improving Ruby on Rails (RoR) performance by patching the stock
garbage collector and compiling your own ruby interpreter. This is
a pain in the ass if you are managing a bunch of boxes.
One method to help things that I applied at work recently was adding this
to my app/controllers/application_controller.rb file. I got an improvement
in execution time of a particularly tough action from about 750 ms down to
200 ms using this technique. With that said, I felt very dirty applying it.
It is definitely a "Rob Peter to pay Paul" moment and I wonder where the
time I robbed is going to come back and and bite me in the ass.
I don't recommend this in practice. I have a feeling the app will suffer
performance burps every once in a while as accumulated garbage is collected
every N requests. But so far, it seems to be working in a staging
environment. Time will tell ...
9/18/2009: Rather than hack around to disguise a problem, analyze the
reason for the problem ...
After modifying the above around filter as follows ...
classApplicationControlleraround_filter:no_gcdefno_gcGC.disablebeginstart_count=ObjectSpace.each_object{}yieldend_count=ObjectSpace.each_object{}logger.info("OBJECTS CREATED = #{end_count-start_count}")ensureGC.enableendendend
I have determined that the action I am profiling is creating a boatload of
objects (89K+ per request!!). No wonder we are having GC issues. By
turning off the garbage collector, we put a temporary band aid on a real
problem. My initial instincts about this solution were correct: it smells.
We still haven't figured out where all the object creations are coming from,
but now that we know what to look for, it shouldn't be too hard to find
them.