IO not closed by GC


#1

Hello,

I often use constructions like the following:

os = IO.popen(‘uname -sr’).readlines.to_s.strip

I assume that the Garbage Collector throws away the IO instance created
by IO::popen, because it’s simply not needed after that line anymore.

What I’ve experienced is, that it leaves a zombie for each time I use
such an instruction.


loop {
zombies = IO.popen(‘ps ax|grep defunct|wc -l’).readlines.to_s.strip
puts “Number of zombies: #{zombies}”
}


This code produces about 100 defunct processes in about 2 seconds.
Operating system is FreeBSD 6.1-RC.

However, if I close the IO object manually, defunct processes stay
constantly at 2-3.


loop {
io = IO.popen(‘ps ax|grep defunct|wc -l’)
zombies = io.readlines.to_s.strip
io.close
puts “Number of zombies: #{zombies}”
}


Is this assumed behaviour or a bug? I guess there’s a close(2) or
waitpid(2) missing in the IO code…

Stephan.


#2

On Apr 17, 2006, at 6:55 PM, Stephan M. wrote:

Is this assumed behaviour or a bug? I guess there’s a close(2) or
waitpid(2) missing in the IO code…

See ``ri IO#close’’. Use the block form if you do not want to call
close manually.

os = IO.popen(‘uname -sr’).readlines.to_s.strip

Calling IO#readlines.to_s is a rather indirect way of calling IO#read.

Try:

 os = `uname -sr`.strip

or

 os = %x{uname -sr}.strip

– Daniel