JRuby - How to start the garbage collector?

garbage-collection, jruby, jvm

Solution

The exact answer to your question would be:

require 'java'

java_import 'java.lang.System'

# ...

System.gc()

though, bearing in mind even though the JVM usually does run the GC, it may or may not do it – very dependent on the JVM implementation. It can also be quite a hit on performance.

A better answer is obviously to ensure that at the end of the nested loop, no reference is held on the test data you are generating, so that they can indeed be reclaimed by the GC later on. Example:

class Foo; end

sleep(5)

ary = []
100_000.times { 100_000.times{  ary << Foo.new }; puts 'Done'; ary = [] }

If you run this with `jruby -J-verbose:gc foo.rb`, you should see the GC regularly claiming the objects; this is also quite clear using JVisualVM (the `sleep` in the example is to give some time to connect to the Jruby process in JVisualVM).

Lastly you can increase heap memory by adding the following flag: `-J-Xmx256m`; see the JRuby wiki for more details.

Edit: Coincidentally, here is a mindmap on GC tuning recently presented by Mario Camou at Madrid DevOps re-posted by Nick Sieger.

Problem

I fired up my JRuby irb console and typed: ``` irb(main):037:0* GC.enable (irb):37 warning: GC.enable does nothing on JRuby => true irb(main):038:0> GC.start => nil irb(main):039:0> ``` How can I manually enable or start the JVM garbage during a program? I ask because I have a program which is needs to generate about 500 MBytes of test data and save it in MySQL. The program uses about 5 levels of nested loops, and it crashes with a JVM memory heap exception after generating about 100 MBytes of test data because there is no more heap memory. I would like to give let the garbage collector run after every run of the outer loop so that all the orphaned objects created in the inner loops can be cleaned up .

Original source