|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
cfp2:~ > cat a.rb
#! /usr/bin/env ruby require 'net/http' 3.times do Net::HTTP.start('www.google.com') do |http| http_response = http.get '/' end p ObjectSpace.each_object(Net::HTTPResponse){} end cfp2:~ > ruby a.rb 1 2 3 why is this leaking Net::HTTPResponse objects? a @ http://codeforpeople.com/ -- share your knowledge. it's a way to achieve immortality. h.h. the 14th dalai lama |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
> why is this leaking Net::HTTPResponse objects?
I don't know, but jruby has the exact same behaviour. Maybe that s? |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Wednesday 09 January 2008 04:23:23 ara howard wrote:
> why is this leaking Net::HTTPResponse objects? It does not leak, objects are just not immediately released by the GC. Try it running 1000 times (on local server preferably). Jan |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
[Note: parts of this message were removed to make it a legal post.]
Why are you assuming it's leaking without giving the GC a chance to run? require 'net/http' 3.times do Net::HTTP.start('www.google.com') do |http| http_response = http.get '/' end p ObjectSpace.each_object(Net::HTTPResponse){} end p "Force GC" ObjectSpace.garbage_collect p ObjectSpace.each_object(Net::HTTPResponse){} C:\>ruby test.rb 1 2 3 "Force GC" 0 MBL On Jan 8, 2008 10:23 PM, ara howard <ara.t.howard@gmail.com> wrote: > cfp2:~ > cat a.rb > #! /usr/bin/env ruby > > require 'net/http' > > 3.times do > Net::HTTP.start('www.google.com') do |http| > http_response = http.get '/' > end > > p ObjectSpace.each_object(Net::HTTPResponse){} > end > > > cfp2:~ > ruby a.rb > 1 > 2 > 3 > > > why is this leaking Net::HTTPResponse objects? > > > a @ http://codeforpeople.com/ > -- > share your knowledge. it's a way to achieve immortality. > h.h. the 14th dalai lama > > > > |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Jan 8, 2008, at 8:53 PM, Michael Bevilacqua-Linn wrote: > Why are you assuming it's leaking without giving the GC a chance to > run? because i'm an idiot and pasted the wrong buffer. here is the code: # # distilled behaviour from dike.rb # class Object Methods = instance_methods.inject(Hash.new){|h, m| h.update m => instance_method(m)} end class Class Methods = instance_methods.inject(Hash.new){|h, m| h.update m => instance_method(m)} def new *a, &b object = Methods["new"].bind(self).call *a, &b ensure ObjectSpace.define_finalizer object, finalizer end def finalizer lambda{} end end # # the above makes this code leaks, but *only* Net::HTTPOK objects # require "net/http" def leak! Net::HTTP.start("localhost") do |http| puts http.get('/').code end end 3.times { puts "---" p ObjectSpace.each_object(Net::HTTPResponse){} leak! GC.start } a @ http://codeforpeople.com/ -- we can deny everything, except that we have the possibility of being better. simply reflect on that. h.h. the 14th dalai lama |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Jan 8, 2008, at 8:45 PM, Jan Dvorak wrote: > It does not leak, objects are just not immediately released by the > GC. Try it > running 1000 times (on local server preferably). as i already posted - i posted the wrong code. here is an even more distilled version: cfp2:~ > cat a.rb # # distilled behaviour from dike.rb # class Class Finalizer = lambda {} def leak_free_finalizer Finalizer end def leaky_finalizer lambda{} end def finalizer %r/leak/ =~ ARGV.first ? leaky_finalizer : leak_free_finalizer end def new *a, &b object = allocate object.send :initialize, *a, &b object ensure ObjectSpace.define_finalizer object, finalizer end end # # the above makes this code leak iff ARGV has "leak" in it # require "yaml" 7.times { GC.start y Array.name => ObjectSpace.each_object(Array){} Array.new } cfp2:~ > ruby a.rb --- Array: 21 --- Array: 49 --- Array: 58 --- Array: 58 --- Array: 58 --- Array: 58 --- Array: 58 cfp2:~ > ruby a.rb leak --- Array: 21 --- Array: 38 --- Array: 54 --- Array: 67 --- Array: 79 --- Array: 91 --- Array: 103 so.... why does installing a static finalizer work ok, but a dynamic one leaks memory!? i'm nice and confused now. a @ http://codeforpeople.com/ -- share your knowledge. it's a way to achieve immortality. h.h. the 14th dalai lama |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Jan 9, 2008, at 2:41 AM, Robert Klemme wrote: > 'd say you picked the wrong class for your tests - apparently a > lambda uses an array somehow. This is what I see from the modified > script (attached): hmmm. doing this in irb suggests not: list = [] GC.start; p ObjectSpace.each_object(Array){}; list << lambda{} GC.start; p ObjectSpace.each_object(Array){}; list << lambda{} GC.start; p ObjectSpace.each_object(Array){}; list << lambda{} GC.start; p ObjectSpace.each_object(Array){}; list << lambda{} the number of Array's will remain static. hrrrmmm.... a @ http://codeforpeople.com/ -- share your knowledge. it's a way to achieve immortality. h.h. the 14th dalai lama |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
> so.... why does installing a static finalizer work ok, but a dynamic
> one leaks memory!? My guess is that the lambda is keeping the scope of the new invocation around, which includes a reference to the newly created array. Would it be a better test not to use Array (instances of which seems to be created also by ObjectSpace / YAML)? Ex: class Foo ; end 7.times { GC.start count = ObjectSpace.each_object(Foo) p "Count: #{count}" Foo.new } -Dan |
|
![]() |
| Outils de la discussion | |
|
|