ruby - Ruby 中使用循环对象引用的垃圾收集

标签 ruby garbage-collection

我在 Ruby 中遇到垃圾回收问题,我认为应该进行垃圾回收的对象没有被垃圾回收。

require 'ruby-mass'

def find_dependencies(_object_id,_mapped = {})
  mapped = _mapped
  points_to_object = Mass.references(Mass[_object_id])
  ids = points_to_object.keys.map{|x| /\#(\d*)/.match(x).captures.first.to_i}
  mapped[_object_id] = ids

  unmapped = ids - mapped.keys
  unmapped.each do |x|
    new_deps = find_dependencies(x,mapped)
    mapped.merge(new_deps)
  end
  mapped
end

做一些制作对象的事情,并找到相关的对象 ID。 GC.start,然后:

> find_dependencies(144789180)
=> {144789180=>[61895480, 144786340, 147807540],
 61895480=>[144789180],
 144786340=>[144789180],
 147807540=>[144789180]}

这里看起来好像有一个循环引用模式,但它完全包含在这四个对象中,所以 Mark-and-Sweep 收集器应该找到它们并将它们移除。

所以,要么我的 find_dependencies_function、Mass gem 或 Ruby 的垃圾收集器中存在错误。我如何缩小范围以找出问题所在并解决此内存泄漏?

最佳答案

Ruby 中的 GC 基本上是这样工作的:

  1. 将所有全局对象标记为事件。

  2. 扫过对象,垃圾收集,除非 parent 是活的。

因此,在循环引用的情况下,A 持有 B 持有 A 将得到 GC,因为两者都没有被事件对象持有。

根据评论,某些东西一定会在某处捕获对象......或者 Mass 正在捕获 RangeError 或其他东西......

>> a = {}
=> {}
>> a[:a] = a
=> {:a=>{...}}
>> a.object_id
=> 2269556540
>> a = nil
=> nil
>> GC.start
=> nil
>> ObjectSpace._id2ref(2269556540)
RangeError: 0x8746af3c is recycled object
    from (irb):17:in `_id2ref'
    from (irb):17

关于ruby - Ruby 中使用循环对象引用的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15710940/

相关文章:

c# - readonly 修饰符会影响垃圾收集器吗?

haskell - 基于物理内存运行GC

ruby-on-rails - 基于 ruby​​ on Rails 中的另一个下拉菜单填充下拉菜单

ruby-on-rails - Rails - 事件模型序列化序列化程序中的哈希数组

mysql - 在 MySQL 中表示无穷大

java - UseCMSCompactAtFullCollection 可以在Sun JDK6 中使用吗?

ruby-on-rails - Heroku 301 重定向

ruby-on-rails - Heroku、Rails:PG::SyntaxError

javascript - parentNode 在 Javascript 内部闭包中丢失? Chrome 错误?

java - GC 输出说明