Bug #1392
closed
Object#extend leaks memory on Ruby 1.9.1
Added by oldmoe (Muhammad Ali) over 15 years ago.
Updated over 13 years ago.
ruby -v:
ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux]
Description
=begin
A few bytes are leaked every time Object#extend is called, here is a sample 1.9.1 script
This code is Ruby 1.9.x and above only¶
@extend = ARGV[0]
module BetterHash
def blabla
end
end
unless @extend
class Hash
include BetterHash
end
end
t = Time.now
1_000_000.times do
s = {}
s.extend BetterHash if @extend
end
after = Time.now - t
puts "done with #{GC.count} gc runs after #{after} seconds"
sleep # so that it doesn't exit before we check the memory
more details here :
http://oldmoe.blogspot.com/2009/04/objectextend-leaks-memory-on-ruby-191.html
oldmoe
=end
Files
- Status changed from Open to Rejected
=begin
I think you can tell if it was a leak by running a loop
loop do
s = {}
s.extend BetterHash if @extend
end
If this eats up all memory in the system then it's a leak. [on mine it stays constant at 4MB].
That doesn't mean to say there's no bugs in there, though--it may be the case that you're using up the entire freelist each time, without ever passing the malloc_limit, which means that your heap total size will get bigger and bigger and bigger...not sure though.
Compiling 1.9 with the GC stats turned on might help.
Cheers!
-=r
=end
=begin
I've just tried the code above with Ruby 1.9.2 Preview 1 and the current trunk.
I can confirm that this doing
./ruby leak_test.rb LEAK
on the above versions appears to leak memory as ps aux / top reports a 0.8% memory utilization by the time the script has finished running. The memory usage goes up gradually as the program runs. Once the program has hit the sleep command, the memory usage does not go down, even if a GC.start call has been inserted directly above to coerce the Ruby VM to clean up.
Running this under the current 1.8.8 snapshot does not to this, and the memory usage remains constant throughout. Likewise not passing any arguments (so extend is not called) also keeps the memory usage constant under both 1.8.x and 1.9.x branches tested on my system.
I am running an a 64 bit (x64) bit rather than a 32bit (x86) build.
=end
=begin
And just to confirm, using an indefinite loop like Roger points out makes my Ruby process grow continuously. After about 6-8 minutes my Ruby process had grown to 12% of memory usage and showed no sign of going down.
=end
=begin
yeah I can confirm this
loop do
Module.new.clone
end
leaks with 1.9.1p376
but doesn't seem to leak for me with trunk. What script are you using exactly?
-r
=end
=begin
My trunk build is: ruby 1.9.2dev (2010-01-27 trunk 26434) [x86_64-linux]
Your clone code above doesn't leak either for me.
However both of these simplified scenarios leak:
./ruby -e 'loop { Class.new.send :include, Module.new }'
./ruby -e 'loop { Module.new.extend Module.new }'
While I'm no C guru, I'm guessing the issue will be relating to include_class_new in class.c or at least it doesn't look like a garbage collection issue given that your clone seems OK.
=end
=begin
I wrote a patch for this issue.
Unless any objections, I will commit later.
=end
=begin
Thanks for the quick patch. It certainly seems to do the trick.
=end
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
This issue was solved with changeset r26515.
Muhammad, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end
=begin
Thanks for fixing this. Seems to now not leak for this version.
ruby 1.9.2dev (2010-02-01 trunk 26538) [i386-mingw32]
=end
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0