Many months later I finally figured out how to make it leak on command, and the results are described below and on the mailing list:

https://lists.gnu.org/archive/html/emacs-devel/2015-09/msg00619.html

Apparently starting up a daemon and then repeatedly creating/destroying a client frame made the memory use consistently climb. The following zsh snippet tickles this bug:

$ emacs --daemon $ while true; do for i in `seq 10`; do timeout 5 emacsclient -a '' -c & ; done; sleep 10; done

The memory use could be monitored with this bit of zsh :

$ while true; do ps -h -p `pidof emacs` -O rss; sleep 1; done

The leak was visible both with emacs -Q (don't load any user configuration) and with emacs (load my full configuration), but the leak was much more pronounced if my configuration was loaded. I then bisected my configuration to find the bit that was causing the leak, and I found it: winner-mode .

Apparently winner-mode keeps a list of all active frames, but it doesn't clean dead frames off of this list. In a long-running daemon workflow frames are created and destroyed all the time, so this list ends up keeping references to data structures that are no longer active. This in turn prevents the GC from cleaning up the associated memory. A simple patch to winner-mode fixes this, and we can clearly see the results:

So I fixed a memory leak. It's not obvious that this is the memory leak that I'm feeling most. And clearly there are other leaks, since the memory consumption is growing even with no configuration loaded at all. Still, we're on our way.