【问题标题】:JRuby - How to start the garbage collector?JRuby - 如何启动垃圾收集器?
【发布时间】:2012-05-31 04:20:36
【问题描述】:

我启动了我的 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 内存堆异常。我想让垃圾收集器在每次运行外循环后运行,以便清理内循环中创建的所有孤立对象。

【问题讨论】:

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

标签: garbage-collection jvm jruby


【解决方案1】:

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

【讨论】:

  • 这不是真的。您有一些中肯的建议,但可以手动运行 GC。
【解决方案2】:

您的问题的确切答案是:

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 2019-06-07
相关资源
最近更新 更多