2013-07-14 27 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