One of the strengths—or weaknesses, depending on your point of view—of Lisp is garbage collection. That means that memory no longer in use is automatically collected and made available to the system without depending on the programmer to release it the way we do in, say, C. Of course, that comes at a cost. Garbage collection can block other operations while it’s running. That’s especially true in the single threaded Emacs.
One often sees complaints about this in the various forums. There’s all sort of advice about what to do. Some say you should set the garbage collection threshold (the amount of collectible memory) high so that garbage collection isn’t triggered as often. Of course, that means that it takes longer to collect the unused memory.
Another suggestion is to set the threshold low so that unused memory can be collected quickly. That means, though, that garbage collection is run more often. Depending on your workflow, either—or possibly both—of these strategies may work well for you.
There’s a third, arguably better, strategy: only garbage collect when the system is idle. That’s facile advice, of course, because it begs the question of how you know when the system is idle. There’s a useful heuristic. If the system has been idle for x seconds it will probably continue being idle long enough for a garbage collection cycle. The question then boils down to the proper value for x.
Jack Jamison believes x should be small and uses 1.2 seconds in his implementation of this strategy. He says that he’s had excellent results with that value. The older GCMH system uses 15 seconds.
I’ve been using GCMH was several years and can’t remember having any garbage collection issues since I started. GCHH lets you configure the idle time but the 15 second setting has been working well for me so I’m not inclined to mess with it.
In any event, if your Emacs is experiencing garbage collection delays it’s worth trying this strategy. If you want a simple prepackaged solution, GCMH is for you. If you want to keep everything in your init.el
and avoid external packages, take a look at Jamison’s post to get started.