如何设置 gc-cons-threshold 的值

在 macOS 上用 Emacs 总感觉卡,今天 Profile 了一下发现有很多 GC,这才发现之前东拼西凑的配置里面把 GC threshold 设置成了 400MB :rofl: 想想现在 App 动辄十几个GB的内存占用,我的 Emacs 在 400MB 限制下跑了这么久,真的是难为它了……

但是我又发现很多帖子里面推荐设定一个较小值,有点迷糊应该怎么设置了…

-  (setq gc-cons-threshold (* 400 (expt 2 20))
+  (setq gc-cons-threshold (* 2 (expt 2 30))
         gc-cons-percentage 0.6)

这个值太大的话,一旦触发GC,Emacs会卡很久。太小的话,频繁触发GC,会感觉一顿一顿的。

400mb作为运行内存应该够用了, App 动辄十几个GB的内存占用 通常指的是app连数据在内的总占用空间大小. 如果运行内存就要十几个GB, 大部分人估计会直接把app删掉, 因为要求太高一般电脑运行不了

有没有可能十几个 GB 是指虚拟内存,GC 的阈值也不等于运行内存

可以用gcmh包,不需要自己设置了。

至少先看一下 gc-cons-threshold 文档的第一句话

https://www.reddit.com/r/emacs/comments/1cyn1ah/emacs_with_modified_gc_threshold_freezes_on_save/

https://emacsconf.org/2023/talks/gc/

看过相关讨论之后我取消了gcmh,手动设置成了256MB

我的 early-init.el

;; NOTE: This GCMH minimizes GC interference with the activity by using a high GC
;; threshold during normal use, then when Emacs is idling, GC is triggered and a
;; low threshold is set. We set the threshold (`gc-cons-threshold'
;; variable) to an unlimited size in "early-init.el", this helps improving the
;; startup time, but needs to be set down to a more reasonable value after Emacs
;; gets loaded. The use of `gcmh-mode' ensures reverting this value so we don't
;; need to do it manually. -- I changed this configuration, see my comments around
;; my setup of gcmh
(setq
 ;; set a high value before initialization, and it should be reduced to a
 ;; proper value after init
 gc-cons-threshold most-positive-fixnum
 gc-cons-percentage 0.3
 read-process-output-max (* 10 1024 1024))

(defun mk/setup-gc()
  (setq
   gc-cons-threshold (* 100 1024 1024)
   gc-cons-percentage 0.3
   read-process-output-max (* 10 1024 1024)
   
   ;; Don’t compact font caches during GC.
   inhibit-compacting-font-caches t))
(add-hook 'after-init-hook #'mk/setup-gc)

这个值还是得根据自己的体验来设置,可以多试试不同的值

1 个赞

你可以把gc信息展示在 modeline, tabline 或者 header line上:

(setq-default
   header-line-format
   '("GC: " (:eval (number-to-string gcs-done)) " - " (:eval (number-to-string gc-elapsed)) "s"))

两个数字,一个是gc次数,一个是gc花费的总时间

1 个赞

还真是。。竟然是 cons 的数据量,但是为啥 400 MB 还能 GC 触发这么频繁 :rofl:

怪不得他叫 gc-cons-threshold,我还在想这 cons 放这里是个啥意思…… 抄配置没动脑子……

这是个好办法,已经用上了 :+1:

我是想的 IDE 和 浏览器,几个G 还是有的…

你对变量含义理解有误

现在ide都内置浏览器吧(或基于浏览器实现),几个G是开了几十上百个页面,每个页面都有一个独立子进程,全部加进来有几个G,只看单个进程的话,应该也没有400M, 扫了一下我电脑上目前还没有400M的单个进程