Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: JRuby 1.6.6
-
Fix Version/s: JRuby 1.6.8
-
Component/s: Encoding, Rails WAR Deployment
-
Labels:None
-
Environment:Linux w/ OpenJDK 1.6.0_23
-
Number of attachments :
Description
If one loads JRuby from a new classloader (different from that of the current thread), instantiates a Ruby instance, then tearDown and nullifies the Ruby instance, the JRuby classes loaded by the new classloader are not freed because an object that extends ThreadLocal remains and references that classloader. At least one such ThreadLocal appears to be at org/jruby/RubyEncoding.java:265 stored in UTF8_CODER.
I've detailed sample code that both shows the leak and works around it: http://stackoverflow.com/questions/9541207/loading-jruby-at-runtime-and-classloader-leak
A rough outline is:
In a loop in a single thread:
load JRuby from a new classloader
instantiate Ruby from that classloader
tear it down
PermGen space OutOfMemoryException after several (~13) iterations
Work around:
In a loop in a single thread:
load JRuby from a new classloader
instantiate Ruby from that classloader in a separate thread
tear it down
stop that thread
100 iterations complete with no problems
I see there are other ThreadLocal bugs reported here, some of relevance to running with JRuby-Rack and/or servlet containers. Not sure if this is fixable or if it just must be lived with. Is being redeployable in a servlet container currently possible and/or a JRuby goal?
Some relevant references: http://wiki.apache.org/tomcat/MemoryLeakProtection
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6254531
Drat...you are absolutely right. This needs to be fixed, perhaps with a weak/soft reference or by some other mechanism.