Skip to content

Instantly share code, notes, and snippets.

@anticomputer
Created April 2, 2020 04:07
Show Gist options
  • Save anticomputer/54e672fb13c76e76a4e7a7ec26d5506c to your computer and use it in GitHub Desktop.
Save anticomputer/54e672fb13c76e76a4e7a7ec26d5506c to your computer and use it in GitHub Desktop.
little emacs gc "hack" that's served me well
(defvar my/enable-forgiving-gc t "Toggle forgiving gc logic.")
;; set a very large gc-cons-threshold (1GB) so we don't garbage
;; collect when I'm interacting with emacs ... BUT we also want
;; to prevent filling up to a large garbage pile when idle for
;; a long period of time (e.g. overnight), so we reschedule for
;; an interval seconds of idle time ... this way we should prevent
;; both gc when typing but also prevent gc-cons-threshold from
;; actually being reached and potentially triggering a very long gc
;; note: this handy if you want to run fancy modelines and other
;; things that aren't necessarily super memory efficient but either
;; way it generally makes emacs feel more snappy and responsive
(when my/enable-forgiving-gc
(setq gc-cons-threshold (* 1024 1024 1024))
;; when we go idle for long periods of time, this is the interval at which gc occurs
(defvar my/idle-timer-gc-idle-interval 60 "GC timer idle interval in seconds.")
;; how long we need to be idle for, for a single gc to occur ... keep this small
(defvar my/idle-timer-gc-init-interval 2 "GC timer init interval in seconds.")
(defvar my/idle-timer-gc-last nil "Last idle-timer-gc.")
(defun my/idle-timer-gc ()
"Force a garbage collect every MY/IDLE-TIMER-GC_INTERVAL consecutive seconds we are idle."
;; cancel any previous timers to prevent stale/unused timer stacking when user interrupts
(when my/idle-timer-gc-last
(cancel-timer my/idle-timer-gc-last))
;; don't repeat these, just have them stack on while we're idle
(setq my/idle-timer-gc-last
(run-with-idle-timer
(time-add (current-idle-time) my/idle-timer-gc-idle-interval)
nil 'my/idle-timer-gc))
(garbage-collect))
;; kick off the initial timer, on a repeat so we kick in every time we go idle
(run-with-idle-timer my/idle-timer-gc-init-interval t 'my/idle-timer-gc))
;; for debugging this malarky ... seems to work as intended
(setq garbage-collection-messages nil)
(provide 'my-garbage-collector-init)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment