What to do if you think that Emacs leaks memory?
topwill tell you the virtual memory (VIRT) and the resident memory (RES)
pmap -d <pid>will tell you the memory map of a process
cat /proc/<pid>/smapsmay hint you to the memory space which is getting too big
n.b. Substitute your actual Emacs process ID for
<pid>. You can obtain this number within Emacs using
For instance this was in
/proc/25952/smaps. 2580 Mb is much for 180 small buffers open.
09abc000-a72fa000 rw-p 09abc000 00:00 0 [heap] Size: 2580728 kB Rss: 1009120 kB Pss: 1009120 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 57676 kB Private_Dirty: 951444 kB Referenced: 397968 kB Swap: 1571492 kB
M-: (info "(elisp) Memory Usage").
You can examine the following variables:
(garbage-collect) and inspect the results. If it returns
nil, it means no garbage collection is being done and therefore Emacs will only increase in size. This is due to a miscompilation; see below.
I’ve done some leak hunting recently, and wrote some scripts to assist. These are still pretty rough, but have been very helpful, and are effective in finding the culprit if a leak can be triggered. Some (early) documentation: http://notes.secretsauce.net/notes/2015/10/05_memory-leak-debugging-tools.html
You can go through the previous revisions in the version control system until you find the most recent version which didn’t show this behaviour. An easy way to do this is via the bisect operation offered by version control programs.
If a program (like Emacs) seems to want progressively all your computer’s memory there is risk that it will slow down your system or is killed by your kernel. A easy thing you can do is to stop the program via
kill -SIGSTOP <pid> to freeze it (and
SIGCONT to restore it). Then go on with debugging (
What does it mean if you have a very high numbers of conses? Etc.
(this is currently a stub, please help out with ideas)
My emacs routinely grows from a small size to about 300 mb, and then it dies. I have had this for a long time and have no real clue why it happens, other than its a problem in some of the packages I use.
The real problem is that its very difficult to figure out where the memory is consumed.
memory-usage.el by StefanMonnier gives a human readable report of garbage-collect:s output, but doesn’t give any real info about which package owns the memory.
Another idea is to create a “memory meter” in the modeline, then it would at least be possible to see when memory is consumed, and maybe get a clue. The problem is how to get the information out of garbage-collect.
Yet another idea would be to modify the garbage collector, to make some form of dump to a file, when the “mark” stage occurs. Maybe the dump could be made sufficiently human readable to give some hints where memory goes.
It could also be possible to modify the garb so as to flag an object for “pretend delete”. then a pretend garb would be done, and a measure of how much memory would be reclaimed if that object was to be deleted would be returned.
One day, compiling Emacs as I always did, Emacs started eating memory progressively up to 1 Gb resident and more than 2 Gb virtual at the step when it does
`/bin/pwd`/temacs --batch --load loadup bootstrap. It also froze the system.
The backtrace of that
(gdb) bt #0 0x081d7115 in mark_maybe_object (obj=0) at alloc.c:4114 #1 0x081d7646 in mark_memory (start=0x7da99bd0, end=0xbffff858, offset=0) at alloc.c:4278 #2 0x081d7700 in mark_stack () at alloc.c:4532 #3 0x081d83bb in Fgarbage_collect () at alloc.c:5103 #4 0x081f4de5 in Ffuncall (nargs=3, args=0x7da99e00) at eval.c:2979 #5 0x081f4c5e in call2 (fn=0, arg1=138577505, arg2=171542709) at eval.c:2852 #6 0x081f2e93 in Fsignal (error_symbol=138577505, data=171542709) at eval.c:1678 #7 0x081f30a5 in xsignal (error_symbol=138577505, data=171542709) at eval.c:1751 #8 0x081f30e4 in xsignal1 (error_symbol=138577505, arg=0) at eval.c:1768 #9 0x081f5359 in Ffuncall (nargs=3, args=0x7da99f30) at eval.c:3097 #10 0x081f4c5e in call2 (fn=0, arg1=138577505, arg2=171542701) at eval.c:2852 #11 0x081f2e93 in Fsignal (error_symbol=138577505, data=171542701) at eval.c:1678 #12 0x081f30a5 in xsignal (error_symbol=138577505, data=171542701) at eval.c:1751 #13 0x081f30e4 in xsignal1 (error_symbol=138577505, arg=0) at eval.c:1768 …
I tried to see the outer stack trace but gdb itself want to take >1’7 Gb for that and crashed with
/build/buildd/gdb-6.8/gdb/utils.c:905: internal-error: virtual memory exhausted: can't allocate 4096 bytes.
In addition, I recently compiled this code successfully. The resulting binary shows this message when entering: Warning (initialization): Building Emacs overflowed pure space. (See the node Pure Storage in the Lisp manual for details.)
It works slower and grows in size more and more (above in this page are some results from that Emacs instance). This makes sense because, according to the documentation, the resulting Emacs will not do garbage collection.
Apparently this has some relation to this line of code in
#define BASE_PURESIZE (1260000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
It was later increased to 1270000. But the original problem was due to this recent change. After reverting it, everyone could compile Emacs again and they lived happily ever after.
– 6.Aug.2009 DanielClemente