2013-07-14 29 views
1

我在Pry玩垃圾收集時發現,由於某種原因,它似乎不起作用。我嘗試了不同的方式來設置我的大陣列爲nil等,同時打破了我的頭:「爲什麼在這個世界上,我無法用GC.start釋放令人恐懼的內存?」GC.start在Pry中沒有效果,但是在IRB中有效

然後我去了IRB,突然它就起作用了!我想知道是什麼原因造成的,如果你不知道答案但找到了答案,我也想知道如何。

我簡單的代碼(我在1.9.3-P327,和提防,這將吃掉1-2音樂會):

a = [] 
for i in (1..1000000) 
    a[i] = 'x' * 100 
end 

在這裏,我後來發現內存增加,然後:

for i in (1..1000000) 
    a[i] = i 
end 

然後,

GC.start 
+0

出於某種原因,當時我在寫這個,我成功地使GC.start實際解除分配。現在我再試一次,它什麼都不做。 Ruby的魔力...... – valk

回答

3

這是因爲Pry stores the output of the last 100 commands by default。因此,您的對象仍然被引用,並且不會被垃圾收集,直到運行足夠的命令將其推出Pry的輸出歷史記錄。

您應該能夠使用_out_找到當前撬實例的輸出歷史物件:

Pry.memory_size = 1 

_out_.to_a 

您可以在您的~/.pryrc調用Pry.memory_size=改變保存先前的結果的默認數量

或暫時在運行中的Pry(將刪除所有現有的歷史記錄):

_pry_.memory_size = 1 

我們可以看到這方面的工作,像這樣:

$ pry 
_pry_.memory_size = 100 # default 
class C; end 

C.new 
ObjectSpace.each_object.grep(C).count #=> 1 

GC.start 
ObjectSpace.each_object.grep(C).count #=> 1 
$ pry 
_pry_.memory_size = 0 
class C; end 

C.new 
ObjectSpace.each_object.grep(C).count #=> 1 

GC.start 
ObjectSpace.each_object.grep(C).count #=> 0 
+0

而且,在進程級別上,內存不會被解除分配。它只是「內部」釋放的。我可以在任務管理器中觀察這一點。 – valk

+0

@valk不確定你的意思。該對象是垃圾回收,其他任何東西都與Pry無關,並且是Ruby所做的。查看我的更新。 –

+0

好的,我需要將問題標記爲:爲什麼Ruby進程使用正在運行的Pry不會釋放內存。 – valk