Ruby 2.x中的垃圾收集

时间:2016-09-08 10:34:29

标签: ruby garbage-collection

我的函数有一个具有100个键值对的散列。 在函数结束时将它设置为nil会使ruby释放该内存还是帮助这个变量更容易被垃圾收集?

def func
  hash ##a very big hash object
  ##Processing
  hash = nil
end

4 个答案:

答案 0 :(得分:2)

不,这些100个键会随着时间的推移而增加heap_length,当您将此引用变量重新分配给nil对象时,将不会调用GC。即使此时调用GC.start,heap_free_num值也会增加,但总heap_length将保持不变。当您指定引用变量nil时。它不会调用垃圾收集器,因为仅在通过引入新变量或在调用新代码的情况下增加heap_length所需的ruby进程中调用GC。

答案 1 :(得分:0)

垃圾收集器会收到它已经超出范围并从那里清理干净。执行hash = nil只是更改引用哈希指向,(现在缺少)和原始哈希保留在内存中,直到 GC 通过其众多清理收集它方法

答案 2 :(得分:0)

完全没有。

在对hash = nil进行[冗余]调用之后,立即结束定义局部变量hash 的范围。也就是说,变量将超出范围,下次GC将完成它的工作,它将被收集。

更通用的答案是“不,将变量设置为nil将不会执行与GC相关的任何操作,但它会将嵌套对象的引用计数器减少一个。”在{{{ 1}}包含未从任何其他地方引用的对象,将hash(不一定是hash的值更改为空哈希/任何其他值也可以,)将减少它的嵌套对象的引用量为零,因此会强制它们被垃圾收集。

NB 请参阅JörgWMittag的重要评论。

答案 3 :(得分:0)

tl; dr :不。

更长的解释:

  1. 无论如何,变量超出了方法的最后范围。
  2. 垃圾收集器不一定会在没有任何引用的情况下收集死对象。实际上,根据您拥有的内存量和程序运行时间,垃圾收集器可能永远不会运行,因此根本不会收集任何对象。
  3. 即使垃圾收集器运行,也无法保证它将收集哪些对象,哪些不收集。一些垃圾收集器具有允许运行的最大时间,并且在此期间仅收集尽可能多的对象。
  4. (这应该是显而易见的,但需要重复。)如果有其他对该对象的引用,它首先甚至没有资格进行垃圾收集。
  5. Ruby语言规范没有说明如何管理内存。不同的Ruby实现使用非常不同的内存管理实现,例YARV使用简单的标记扫描收集器,Rubinius使用Immix,而JRuby,IronRuby,Topaz,Opal甚至没有自己的,他们使用底层平台的内存管理。 (这也可能完全不同,例如仅适用于JRuby,HotSpot有4个不同的GC,JRockit有2个,J9有2个。)