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 垃圾?

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

4

2 回答 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 重新发布。

于 2012-05-24T15:57:55.460 回答
-1

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

于 2012-05-25T05:57:52.230 回答