将gc-cons-threshold设置得很高并在闲置时收集垃圾有任何不利之处吗?


17

我在我的顶部添加了以下两行init.el

(setq gc-cons-threshold (eval-when-compile (* 1024 1024 1024)))
(run-with-idle-timer 2 t (lambda () (garbage-collect)))

这意味着Emacs不会在闲置时(即当暂停不打扰我时)这样做,而不是每分配800KB的内存收集垃圾。(它还会在分配1GB内存后收集,但我认为不会发生这种情况)。

这将我的启动时间缩短了大约三分之二。从理论上讲,它还应该总体上提高性能。这种方法有不利之处吗?


1
原则上,您不应gc-cons-threshold在任何给定的时间设置高于您愿意实际达到的值,因为您应该假设自己不时地达到该值(毕竟,谁知道会产生多少垃圾?通过一些意想不到的热情的非空闲任务)。我没有看到使用空闲计时器触发gc的特定问题,但是我认为将非空闲gc的阈值设置为看起来像OTT一样高,我的印象是,该值可能被选择为“高于我“永远需要”,而不是“我愿意使用的最高”。
菲尔斯(Phils)

5
根据Stefan Monnier的这篇文章“最好别碰它。在Emacs-22中,我们引入了gc-cons-percentage,它具有与增加gc-cons-threshold相同的好处,但是没有缺点。而且不必费力。也就是说,我建议用户从其.emacs中删除所有gc-cons-threshold设置。”
izkon

1
@izkon,除了您链接到的帖子可以追溯到2007年,而例如,该帖子实际上是某人进行过实验(并且更改阈值确实有所不同)可以追溯到2016年。因此,它退步了,或者变通了运作良好。
Hi-Angel

1
@Erik我想您可以替换(eval-when-compile (* 1024 1024 1024))most-positive-fixnum (请这样做,我很确定遇到问题的每个人都会将您的代码复制到他们的配置中)
Hi-Angel

2
@ Hi-Angel我认为这不是一个好主意。如果Emacs实际上分配大量内存而没有变得空闲,则应使用gc而不是继续分配,直到系统必须交换甚至完全用尽内存为止。如果有的话,1GB已经太高了。
Erik

Answers:


4

据我所知,如果您有RAM,就可以了,但是如果Emacs在GC'ing之前确实达到了很高的使用率,则可能需要很长时间。我不确定Eli到底是什么意思。ISTM认为,如果您有足够的内存,应该没问题,但是他是这里的专家。

话虽如此,我已经在我的init文件中使用了这些行一段时间,这有助于减少启动时间,而无需使更改永久生效:

;;;;; Startup optimizations

;;;;;; Set garbage collection threshold

;; From https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/

(setq gc-cons-threshold-original gc-cons-threshold)
(setq gc-cons-threshold (* 1024 1024 100))

;;;;;; Set file-name-handler-alist

;; Also from https://www.reddit.com/r/emacs/comments/3kqt6e/2_easy_little_known_steps_to_speed_up_emacs_start/

(setq file-name-handler-alist-original file-name-handler-alist)
(setq file-name-handler-alist nil)

;;;;;; Set deferred timer to reset them

(run-with-idle-timer
 5 nil
 (lambda ()
   (setq gc-cons-threshold gc-cons-threshold-original)
   (setq file-name-handler-alist file-name-handler-alist-original)
   (makunbound 'gc-cons-threshold-original)
   (makunbound 'file-name-handler-alist-original)
   (message "gc-cons-threshold and file-name-handler-alist restored")))

你为什么不使用after-init-hook
艾瑞克(Erik)

3
因为该操作将在初始化后立即运行,这可能会使用户等待GC。通过使用空闲计时器,它可以在用户不使用Emacs时运行。
blujay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.