I have used GCMH (the Garbage Collector Magic Hack) for many years. It’s great.
GCMH hooks itself in pre/post-command hooks. It (re)sets its idle timer on every command, which seems to be a good strategy, but also feels a bit too much.
Conversely, all gc-maybe-mode
does is this:
- with a predefined idle timer (default is 5 seconds), call
garbage-collect-maybe
(from Emacs 28.1 or above) with a factor based on the currentgc-cons-percentage
, so it garbage collects if needed; - add hooks to the
minibuffer-setup-hook
(raising the GC threshold),minibuffer-exit-hook
(restoring the GC threshold), and thepost-gc-hook
(for optional stats in a buffer);
That’s it. It is pretty much the same GCMH hack, but as a cheap trick.
With custom advices, we can raise the threshold (gc-maybe-raise-threshold
or gc-maybe-raise-threshold-briefly
) for known costly functions; with a “restore” timer, we reset to defaults shortly after raising them (gc-maybe-restore-threshold
).
I’m doing this in the very beginning of my init.el
file (before bootstrapping straight.el), so adapt accordingly:
(load "~/.emacs.d/site-lisp/gc-maybe/gc-maybe.el" nil t)
(gc-maybe-raise-threshold)
(add-hook 'after-init-hook 'gc-maybe-restore-threshold 99)
Then, in my config file, with numbers that seems to better fit my machine:
(use-package gc-maybe
:straight (:local-repo "~/.emacs.d/site-lisp/gc-maybe")
:init
(setopt gc-maybe-threshold-default (* 16 1024 1024)) ; 16 MiB
(setopt gc-maybe-percentage-default 0.2)
(gc-maybe-mode +1) ; set minibuffer hooks and idle timer
:config
;; optionally log GCs in a buffer
(setopt gc-maybe-log-stats t)
;; example function advice
(advice-add 'save-buffers-kill-emacs :before #'gc-maybe-raise-threshold))