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

6
我打开了我的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垃圾回收机制?

我是这样问的,因为我有一个需要生成大约500MB测试数据并将其保存在MySQL中的程序。该程序使用大约5层嵌套循环,并在生成大约100 MB测试数据后因没有更多的堆内存而崩溃了。我希望在每次外部循环运行后让垃圾收集器运行,以便清理内部循环中创建的所有孤立对象。


1
这不太可能有帮助,因为如果JVM内存不足,它会在放弃之前运行GC。您可能需要确保不会持有超过所需时间的引用和/或增加堆大小。 - theglauber
2个回答

12
您问题的确切答案是:
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; 有关更多详细信息,请参见JRuby wiki编辑:巧合的是,这里是最近由Mario Camou在马德里DevOps上展示的GC调优思维导图,由Nick Sieger重新发布。

非常感谢你,Sebastien。你的建议非常有用,帮助我们提出(并回答)了比我们想象中更多的问题。 - Jay Godse
谢谢回答。 再举一个例子:https://gist.github.com/Shobhit1/f4ec5c9f1f47f3b8e70bb7d27a78fba9 - shobhit1

-1

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


这不是真的。你提供了一些有用的建议,但是手动运行GC是可能的。 - Overbryd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接