JRuby - 如何启动垃圾收集器?

Jay*_*dse 6 garbage-collection jvm jruby

我启动了我的JRuby irb控制台并键入:

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> 
Run Code Online (Sandbox Code Playgroud)

如何在程序中手动启用或启动JVM垃圾?

我问,因为我有一个程序需要生成大约500 MB的测试数据并将其保存在MySQL中.该程序使用大约5个级别的嵌套循环,并且在生成大约100 MB的测试数据后,它因JVM内存堆异常而崩溃,因为没有更多的堆内存.我想让垃圾收集器在外循环的每次运行之后运行,以便可以清除在内循环中创建的所有孤立对象.

Séb*_*nec 11

你问题的确切答案是:

require 'java'

java_import 'java.lang.System'

# ...

System.gc()
Run Code Online (Sandbox Code Playgroud)

不过,铭记尽管JVM通常运行GC,它可能或不可能做到这一点-非常依赖于JVM实现.它也可以在性能上受到很大影响.

更好的答案显然是确保在嵌套循环结束时,不会对您生成的测试数据进行引用,以便以后GC确实可以回收它们.例:

class Foo; end

sleep(5)

ary = []
100_000.times { 100_000.times{  ary << Foo.new }; puts 'Done'; ary = [] }
Run Code Online (Sandbox Code Playgroud)

如果你运行它jruby -J-verbose:gc foo.rb,你应该看到GC定期声明对象; 使用JVisualVM也很清楚(sleep在示例中是为了给JVisualVM中的Jruby进程提供一些时间).

最后你可以通过添加下面的标记增加堆内存:-J-Xmx256m; 有关更多详细信息,请参阅JRuby wiki.

编辑:巧合的是,这是最近由马里奥·卡姆在马德里DevOps上由尼克· 西格尔重新发布的关于GC调整的思维导图.