2013-03-29 20 views
10

Ben çöp toplama olmalı diye düşündüğüm bir nesne çöp toplanan Ruby'de çöp toplama ile ilgili bir sorun yaşıyorum.Dairesel Nesne ile Ruby Garbarge Koleksiyonu Referanslar

Nesneleri yapan bazı nesneleri yapın ve ilgili nesne kimliğini bulun. Sonra GC.start:

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

orada dairesel referans deseni burada, ama hepsi tamamen bu dört nesneler içerdiği, böylece Mark-ve-Sweep toplayıcı Onları bulup çıkarmak gerekir gibi görünüyor.

Bu yüzden, ya find_dependencies_function, Mass gem ya da Ruby'nin çöp toplayıcısında bir hata var. Sorunun ne olduğunu bulmak ve bu bellek sızıntısını çözmek için bunu nasıl daraltabilirim?

+3

Mark-ve-süpürme şeyler bu tür işleyemez. Bunu yapmak için, toplayıcının tüm ağacı kaldırmasına izin vermek için bu nesnelerdeki WeakRef'i kullanmanız gerekir. – Linuxios

+0

Neden bu şeyleri işaretleyip süpürüp atlayamıyorsunuz? Referans sayımı ile nasıl kaybolacağını görebiliyorum, ama bunlar işaretlenmemeli ve toplanmalı mı? – aaronjg

+0

İlk önce sormam gereken - nesne referansını nasıl kaybedersiniz? Alt nesnelere kesinlikle * hayır * başka referans var mı? – Linuxios

cevap

2

Ruby GC şöyle esasen çalışır:

  1. işaretle canlı olarak tüm genel nesneler. Nesneleri süpürün, bir ebeveyn canlı olmadıkça çöp toplama yapın.

Yani, dairesel referans durumunda, A ne canlı bir nesne tarafından tutuluyor çünkü GC'd alacağı bir tutunarak B tutunan. yorumların Başına

şey mutlaka bir yerde nesnenin üzerine düzenliyor ... Ya da belki Kitle RangeError falan yakalamaktadır ...

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