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

时间:2012-05-24 14:52:10

标签: 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> 

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

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

2 个答案:

答案 0 :(得分:10)

你问题的确切答案是:

require 'java'

java_import 'java.lang.System'

# ...

System.gc()

但是,请记住,即使JVM通常 运行GC,它可能会也可能不会 - 非常依赖于JVM实现。它也可以在性能上受到很大影响。

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

class Foo; end

sleep(5)

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

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

最后,您可以通过添加以下标志来增加堆内存:-J-Xmx256m;有关详细信息,请参阅the JRuby wiki

编辑:巧合的是,最近由Mario Camou在马德里DevOps上发表的a mindmap on GC tuning由Nick Sieger重新发布。

答案 1 :(得分:-1)

这是不可能的,因为Gc将由JVM自动运行。确保只在需要时才创建对象。避免创建类级别对象,并尝试找出哪些对象占用更多内存并仅在需要时创建它。