[Mongrel] [ANN] Mongrel Pre-Release -- Ruby's LEAK Fixed (Death To Mutex!)

Zed Shaw zedshaw at zedshaw.com
Fri Aug 25 23:31:08 EDT 2006

Howdy Folks,

This release is after painstaking analysis of a memory leak that was
reported by Bradley Taylor, reduced by myself, and then fixed after much
work.  You should all thank Bradley for finding the bizarre fix.

It turns out the Ruby has a memory leak when you use pretty much any
thread locking primitive other than Sync (Mutex, Monitor, etc.):


The fix (for whatever reason) is to use Sync and put it in a block:


Those two scripts are mini versions of how Mongrel manages threads so
that I could figure out a solution or get some input.  The graph is
reported ram usage samples 1/second.  As you can see the first leaking
graph goes up and doesn't go down, the second (fixed) graph cycles

** This is a Ruby issue, so if you have software using Mutex or Monitor,
change to Sync now. **

Tests of this latest pre-release show that the RAM is properly cycled by
the GC and that it's actually finally solved.  If you run your app using
this release and you still have a leak then use the memory debugging
tools mongrel has to rule out your code (see below).


* No more allow_concurrency.  Until Ruby's fixed I can't let people do
this anymore.
* USR1 debugging.  If you're wondering about how Mongrel's locking of
Rails impacts your application, or what is causing BAD CLIENT then just
hit your mongrel_rails with USR1 and Mongrel will tell you.
* More extensive and accurate memory debugging.  Use -B and look at the
log/mongrel_log/objects.log to get a good idea of counts of objects,
delta changes in counts, and mean+standard deviation lengths of objects
with length methods.
* Fixes a few places where sockets are closed and left in CLOSE_WAIT.


As per usual:

sudo gem install mongrel --source=http://mongrel.rubyforge.org/releases/

Initial tests show it works on 1.8.5 and is actually faster, but this is
unsupported for now.


If you want to test the memory leak, here's the process:

1) Start your application in *production* mode: 
	mongrel_rails start -e production

2) Hit it with USR1:  
	killall -USR1 mongrel_rails

3) Start running something that prints out the ram (here's my fish
	while sleep 1
	  ps aux | grep mongrel_rails | grep -v grep | grep -v gvim | ruby -aln
-e "puts split[4 .. 5].join(',')"

4) Thrash a simple rails controller with httperf:
	httperf --server --port 3000 --num-conns 1000 --rate 120
--uri /testuri

What you want to do is adjust num-conns and rate until Mongrel reports
"X threads waiting for /testuri..."

The bug only manifests itself when threads pile up behind the guard
around Rails dispatching.  This is also how you'd find out which Rails
actions are too slow.

Please report any bugs you find in this release, and a Win32 release
will come out after I'm sure it works for everyone else.

Zed A. Shaw
http://www.lingr.com/room/3yXhqKbfPy8 -- Come get help.

More information about the Mongrel-users mailing list