Well done for isolating this; a triumph of empirical legwork.
> Amazingly, this seemingly benign method rings a very familiar bell.
> Another developer at Powerset had identified a piece of code in his
> app that looked very much like this and resulted in a HUGE memory leak
> as well. The odd but functional fix that we identified was to create a
> local scope by declaring a local variable. Here's the diff that I will
> try for this test run:
>
> def base_name
> + x = 1
> self.class.name.split('::').last
> end
Odd indeed. This looks like a bug in Ruby. Would Ruby Talk be the
best place to raise this in the hope of solving the problem at source?
Regards,
Andy Stewart
-------
http://airbladesoftware.com
On 15-Feb-08, at 7:53 PM, Tom Werner wrote:
> All I can say is SCIENCE!
>
> I can't tell you how glad I am to have finally solved this problem.
> The fun isn't over yet, though. I'll now confirm the fix for 10
> watches and on 1.8.6. Stay tuned!
Well done!
Here's a test case that demonstrates what is surely a bug. If you
want, you can post on ruby-talk or someplace more efficient to get
some attention and a fix. Make sure you post the test case.
module Play
class Toy
def peek_at_proc
puts `ps u -p #{Process.pid}`
end
def base_name
#x = 1 # <<<<<< REMOVE COMMENT TO FIX MEM LEAK
"a,b".split(',')
end
def test
peek_at_proc
1000000.times do
base_name
end
peek_at_proc
end
end
end
Play::Toy.new.test
class Bar
def self.class_name
name.split(/::/)
end
end
loop { Bar.class_name }
Leaks rather a lot.
--
Kevin Clark
http://glu.ttono.us
He's another Powerset developer, referring to our internal ruby list ;)
This is like Alice in Wonderland. Curiouser and curiouser....
Keep up the good detective work!
Moses
Here's our init.d script for god:
#!/usr/bin/env bash
case "$1" in
start)
RAILS_ENV=production RAILS_ROOT=/your_app_root/current
/usr/bin/god -P /var/run/god.pid -l /var/log/god.log
/usr/bin/god load /your_app_root/current/config/monitor.god
;;
stop)
# stops god, leaves monitored processes running
/usr/bin/god quit
;;
terminate)
# stops god, killing monitored processes
/usr/bin/god terminate
;;
restart)
$0 stop
$0 start
;;
*)
# Unknown argument.
echo "usage: $0 {start|stop|restart|terminate}"
exit 1
;;
esac
exit 0
And the root cron job is:
0 2 * * * /etc/init.d/god restart
We'll be focusing on the memory leak in the coming weeks at Powerset,
so hopefully this won't continue to be a problem for much longer.
Tom
Tom