måndag, november 19, 2007

Ruby memory leaks

They aren't really common, but they do exist. As with any other garbage collected language, you can still be susceptible to memory leaks. In many cases they can also be very insidious. Say that you have a really large Rails application. After some time it grinds to a halt, CPU bound in GC. It may not even be a leak, it could just be something that creates so much garbage that the collector cannot take care of it.

I gotta admit, I'm not sure how to find such a problem. After getting histograms of objects, and trying to profile it, maybe run with ruby-debug, I would be out of options. Maybe some kind of shotgun technique - shutting down parts of the application, trying to pinpoint the location of the problem.

Now, ordinarily, that would have been the end of my search. A failure. Or maybe several weeks of trying to read through the sources.

The alternative? Run the application in JRuby. See if the same memory leak shows up (remember, it might be a bad interaction with MRI's runtime system that gives you grief. Or maybe even a bug in MRI Garbage Collector). But if it doesn't go away, you're in luck. Wait until the CPU starts chugging for real, and then take a heap dump using the jmap Java SDK tool. Once that's done, you'll be sitting with a large honking binary file that you can't do much with. The standard way of reading it is through jhat, but that don't give much to go on.

But then I found this wonderful tool called SAP Memory Analyzer. Google it and download it. It's marvelous. Easily the best heap analyzer I've run across in a long time. It's only flaw is that it runs in Eclipse... But well, it can't be everything, right?

Once you've opened up the file in SAP, you can do pretty much everything. It's quite self explanatory. The way I usually go about things is to use the core option, and then choose "find_leak". That almost always gives me some good suspects that I can continue investigating. From there on it's just to drill down and find out exactly what's going on.

Tell me if you can do that in any way as easy as that with MRI. I would love to know. But right now, JRuby is kicking butt in this regard.

3 kommentarer:

Anonym sa...

You might try running your application with ptrace or valgrind when using MRI.

Unknown sa...

We are going open source beginning of 2008.
So if you don't like the UI, build a new one:)
Special JRuby support could also be something that could be done.


Unknown sa...

Hi Bini,

In my current project, we need to use a Rails model class (extend from ActiveRecord::Base) from Java. When I try to access the class using JSR 223 - ScriptEngine, I got org.jruby.exceptions.RaiseException. It means that the engine couldn't understand the script in the file.

Is there any way to do such thing? I've tried to find an example from Internet but couldn't find anything.

I appreciate much if you can give me some hints.

My email: huythieuhoang@gmail.com