From: Joe Van Dyk Date: 2005-04-28T01:08:00+09:00 Subject: Re: memory leak On 4/26/05, Joe Van Dyk wrote: > eek. copy/paste borked. > > See below for correct version. FYI, you'll need SysVIPC installed (http://deisui.org/~ueno/ruby/sysvipc.html). In essence, the code below starts a thread that uses a object to read from a message queue repeatedly. If there's no messages left on the message queue, the #recv method throws an exception, we catch that and exit the loop. The reader thread then sleeps for a second and reads more messages from the queue. The problem doesn't seem to be with the sending of the message over the message queue, rather its the receive. Somewhere, something isn't being thrown away. I used ObjectSpace to monitor the number of objects that existed. The total number of Objects in memory seem to fluctuate, but don't increase over time (while memory is increasing). I looked at the C code for the SysVIPC module but couldn't see any obvious errors. Any thoughts? Joe > On 4/26/05, Joe Van Dyk wrote: > > Got a memory leak in the following code.. not sure if DRb is necessary > > in it or not. > > > > Put the code into a file named test.rb, btw. > > > > I think I tracked it down to the SystemVIPC::MessageQueue#recv method. > > If I don't give it a high receive length (like 8192), I don't see the > > leak. If I do give it a high length, the program takes up a very > > large amount of space pretty quickly... about an increase of a meg > > every five seconds. > > > > Any ideas? (On my linux system, kernel.msgmax is set to 10000 if it matters) > > > > # test.rb > > require 'drb' > require 'sysvipc' > > class Foo > def initialize > @key = SystemVIPC::ftok("test.rb", 1) > @msg = SystemVIPC::MessageQueue.new(@key, 0777 | SystemVIPC::IPC_CREAT) > end > > def recv > continue = true > while continue > begin > @msg.recv(1, 8192, SystemVIPC::IPC_NOWAIT) > rescue > continue = false > end > end > end > > def send > @msg.send(1, "HELLO WORLD HELLO WORLD") > end > end > > f = Foo.new > some_thread = Thread.new(f) do |foo| > loop do > foo.recv > sleep 1 > end > end > some_thread = Thread.new(f) do |foo| > loop do > foo.send > sleep 1 > end > end > > DRb.start_service('druby://localhost:8000', f) > DRb.thread.join >