GC.start has no effect in Pry, but does in IRB

2019-06-06 22:36发布

问题:

I was playing with garbage collection in Pry, and noticed that for some reason it doesn't seem to work. I was trying different ways to set my big array as nil, etc, while breaking my head on the question "why in the world I simply cannot deallocate the freaking memory with GC.start?"

Then I went to IRB and suddenly it worked! I'm wondering what could cause this, and if you didn't know the answer but found it, I'd also like to know how.

My simple code (I'm on 1.9.3-p327, and beware, this will eat up 1-2 gigs):

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

here, I observed the memory increase, and then later:

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

and then,

GC.start

回答1:

This is because Pry stores the output of the last 100 commands by default. As a result, your object is still referenced and will not be garbage collected until enough commands have been run to push it out of Pry’s output history.

You should be able to find your object in the current Pry instance’s output history using _out_:

_out_.to_a

You can alter the default number of previous results saved by calling Pry.memory_size= in your ~/.pryrc:

Pry.memory_size = 1

or temporarily in a running Pry (will erase all existing history as well):

_pry_.memory_size = 1

We can see this working like so:

$ 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