From: Eric Mahurin Date: 2005-10-16T23:05:59+09:00 Subject: Re: Help! define_method leaking procs... --- "Ara.T.Howard" wrote: > On Sun, 16 Oct 2005, Ara.T.Howard wrote: > > > this is quite suspect: > > > > [ahoward@localhost ~]$ for i in $(seq 0 18);do > > printf "$i => "; > > ruby -e' class << self; (2**ARGV.shift.to_i).times{|n| s = > '42' * n; > > define_method("f#{ n }"){ 42 }}; end; GC::start; p > IO::read("/proc/#{ $$ > > }/status").grep(/VmSize/) ' $i; > > done > > > > 0 => ["VmSize:\t 2840 kB\n"] > > 1 => ["VmSize:\t 2840 kB\n"] > > 2 => ["VmSize:\t 2840 kB\n"] > > 3 => ["VmSize:\t 2840 kB\n"] > > 4 => ["VmSize:\t 2844 kB\n"] > > 5 => ["VmSize:\t 2840 kB\n"] > > 6 => ["VmSize:\t 2840 kB\n"] > > 7 => ["VmSize:\t 2844 kB\n"] > > 8 => ["VmSize:\t 2976 kB\n"] > > 9 => ["VmSize:\t 3456 kB\n"] > > 10 => ["VmSize:\t 3720 kB\n"] > > 11 => ["VmSize:\t 4380 kB\n"] > > 12 => ["VmSize:\t 6072 kB\n"] > > 13 => ["VmSize:\t 9456 kB\n"] > > 14 => ["VmSize:\t 15996 kB\n"] > > 15 => ["VmSize:\t 28704 kB\n"] > > 16 => ["VmSize:\t 53352 kB\n"] > > 17 => ["VmSize:\t 101220 kB\n"] > > 18 => ["VmSize:\t 194404 kB\n"] > > > > > > note the progression is linear until 13 (note irony) and > then climbs > > exponentially - doubling each time. > > and even wrapping in a method doesn't seem to help > > [ahoward@localhost ~]$ ruby a.rb 15 > 1 => VmSize: 2844 kB > 2 => VmSize: 2848 kB > 4 => VmSize: 2848 kB > 8 => VmSize: 2848 kB > 16 => VmSize: 2848 kB > 32 => VmSize: 2848 kB > 64 => VmSize: 2976 kB > 128 => VmSize: 3108 kB > 256 => VmSize: 3724 kB > 512 => VmSize: 4648 kB > 1024 => VmSize: 5572 kB > 2048 => VmSize: 9904 kB > 4096 => VmSize: 13104 kB > 8192 => VmSize: 27016 kB > 16384 => VmSize: 46676 kB > > > [ahoward@localhost ~]$ cat a.rb > class Object > def gen_method > klass = Class === self ? self : self.class > class << klass > define_method("f#{ rand(2 ** 42) }"){ 42 } > end > end > end > > limit = Integer ARGV.shift > > limit.times do |l| > n = 2 ** l > > n.times{|i| s = '42' * i and gen_method} > > GC::start > > printf "% 8d => %s", n, IO::read("/proc/#{ $$ > }/status").grep(/VmSize/) > end > > still exponential after a threshold... The other leaking examples were technically quadratic (O(n**2)) were they should have been O(n). The above one is also O(n). Take on the "s = '42' * i and" and you'll see the same memory usage. I don't see an issue in the above example. It's just that the memory usage was so small for anything below n=1024, that it probably didn't have to grow much beyond what ruby had allocated to it when it started up. __________________________________ Yahoo! Music Unlimited Access over 1 million songs. Try it free. http://music.yahoo.com/unlimited/