2013-03-29 8 views
10

Tôi đang gặp vấn đề với việc thu gom rác trong Ruby nơi một đối tượng mà tôi cho là bộ sưu tập rác không bị thu gom rác.Bộ sưu tập Garbarge trong Ruby với Thông tư Đối tượng Tham khảo

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 

Thực hiện một số nội dung tạo đối tượng và tìm ID đối tượng có liên quan. GC.start, sau đó:

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

Dường như có một mô hình tham chiếu vòng tròn ở đây, nhưng nó là tất cả hoàn toàn chứa trong bốn đối tượng, vì vậy các nhà sưu tập Mark-and-Sweep nên tìm chúng và loại bỏ chúng.

Vì vậy, hoặc có lỗi trong find_dependencies_function của tôi, đá quý khối lượng hoặc bộ thu gom rác của Ruby. Làm cách nào để thu hẹp điều này xuống để tìm hiểu vấn đề là gì và giải quyết sự rò rỉ bộ nhớ này?

+3

Mark-and-quét không thể xử lý những thứ như thế. Để làm điều này, bạn phải sử dụng WeakRef trong các đối tượng đó để cho phép bộ thu loại bỏ toàn bộ cây. – Linuxios

+0

Tại sao không thể đánh dấu và quét xử lý những thứ này? Tôi có thể thấy chúng sẽ trượt qua tính toán tham chiếu như thế nào, nhưng chúng không được đánh dấu và phải được thu thập, phải không? – aaronjg

+0

Lần đầu tiên tôi phải hỏi - làm thế nào để bạn mất tham chiếu đối tượng? Có hoàn toàn * không * tài liệu tham khảo khác để các subobjects? – Linuxios

Trả lời

2

Các GC trong Ruby làm việc cơ bản như sau:

  1. Đánh dấu tất cả đối tượng toàn cầu như sống.

  2. Quét qua các đối tượng, thu gom rác thải trừ khi bố mẹ sống.

Vì vậy, trong trường hợp tham chiếu vòng tròn, A giữ trên B đang nắm giữ lên A sẽ nhận GC do không bị một đối tượng trực tiếp giữ.

mỗi ý kiến, một cái gì đó là nhất thiết phải nắm giữ các đối tượng ở đâu đó ... Hoặc có thể Thánh lễ được bắt RangeError hoặc một cái gì đó ...

>> 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