【问题标题】:Why isn't this simple class garbage collected in Ruby console?为什么 Ruby 控制台不收集这个简单的类垃圾?
【发布时间】:2018-11-28 19:47:17
【问题描述】:

我正在使用 Ruby 垃圾收集器运行一些测试。当我从 Ruby 控制台运行它时,我得到了这个奇怪的行为:

class B
end
#=> nil
count = ObjectSpace.each_object(B) {|x| x }
#=> 0
b = B.new
#=> #<B:0x00007feeb7849678>
count = ObjectSpace.each_object(B) {|x| x }
#=> 1
b = nil
#=>  nil
GC.start
#=> nil
count = ObjectSpace.each_object(B) {|x| x }
#=> 1

为什么会这样?

更新:我只在 PRY 中得到这种行为。在 IRB 中按预期工作(对象被垃圾收集)。

【问题讨论】:

  • 从黑盒的角度来看,这似乎很正常; GC 认为不适合销毁内存中的实例。也许它正在等待执行的某个点或达到某个阈值,但无论如何,它不在你的掌控之中。
  • @ggorlen “......它不在你的手中”不一定。如果你真的想强制收集一些东西,你可以在技术上WeakRef 它,虽然绝对不推荐,因为它可能被内部 GC 而不是显式的GC.start 消耗。只需在 GC.start 之前添加 b = WeakRef.new(b) 即可导致此代码生成 0
  • 无法复制。您的示例代码按预期对我有用,即最后一个计数返回0

标签: ruby garbage-collection


【解决方案1】:

垃圾收集器仅在绝对必要时收集垃圾。收藏很贵。

除非内存不足,否则您的对象不太可能被垃圾回收。

注意:这显然高度依赖于具体实现,具体实现的具体版本,以及你使用的具体环境。例如。 Rubinius 的 GC 与 YARV 的完全不同,YARV 的 GC 与 MRuby 的完全不同。即使在 YARV 中,GC 在版本之间也发生了显着变化。 TruffleRuby、JRuby、IronRuby、MagLev 和 Opal 甚至根本没有 GC,它们依赖于底层平台的内存管理。

【讨论】:

    【解决方案2】:

    看来another question已经回答了这个问题

    Pry 存储最后 100 条命令的输出,因此该对象实际上不能被垃圾回收。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-10
      • 2011-12-05
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      相关资源
      最近更新 更多