Есть ли какой-либо недостаток в том, чтобы установить `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)))

Это означает, что вместо сбора мусора каждые 800 КБ выделенной памяти, Emacs делает это в режиме ожидания, то есть когда пауза не беспокоит меня. (Он также собирается после выделения 1 ГБ памяти, но я не думаю, что это произойдет).

Это улучшило мое время запуска примерно на две трети. Теоретически, это также должно улучшить производительность в целом. Есть ли недостатки этого подхода?

Erik
источник
1
В принципе, вам не следует устанавливать gc-cons-thresholdболее высокое значение, чем вы действительно хотите достичь в любой момент времени, потому что вы должны предполагать, что время от времени вы будете достигать этого значения (в конце концов, кто знает, сколько мусора может накопиться какой-то неожиданно-восторженной не праздной задачей). Я не вижу особой проблемы с запуском gc с таймером простоя, но я думаю, что установив порог для неактивного gc так высоко, как кажется OTT, и у меня сложилось впечатление, что значение, вероятно, было выбрано как «выше, чем я». мне когда-нибудь понадобится "а не" самый высокий, который я готов использовать ".
Фил
5
Согласно этому посту Стефана Монье : «Лучше не трогать его. В Emacs-22 мы ввели gc-cons-процент, который дает то же преимущество, что и увеличение порога gc-cons, но без недостатков. И без необходимости возиться с ним». Т.е. я бы порекомендовал пользователям удалить любые настройки gc-cons-threshold из своих .emacs. "
Изкон
1
@izkon, за исключением того, что пост, на который вы ссылались, датируется 2007 годом, в то время как, например, этот пост , где кто-то на самом деле экспериментировал - и изменение порога действительно имело значение - датируется 2016 годом. Так что либо это регресс, либо обходной путь просто никогда работал хорошо.
Привет, Ангел,
1
@ Эрик Я думаю, вы можете заменить (eval-when-compile (* 1024 1024 1024))на most-positive-fixnum (пожалуйста, сделайте это, я уверен, что каждый, кто сталкивается с вашим вопросом, копирует ваш код в свою конфигурацию) .
Привет, Ангел,
2
@ Привет, Ангел, я не думаю, что это хорошая идея. Если Emacs фактически выделяет огромные объемы памяти, не становясь бездействующим, он должен gc вместо того, чтобы продолжать выделять, пока система не должна поменяться местами или даже не исчерпает память полностью. Во всяком случае, 1 ГБ уже слишком много.
Эрик

Ответы:

4

Насколько я знаю, если у вас есть ОЗУ, это нормально, но если Emacs когда-либо достигнет очень высокого уровня использования до GC'ing, это может занять много времени. Я не уверен точно, что означает Илай; ISTM, что если у вас достаточно памяти, все будет хорошо, но он здесь эксперт.

Сказав это, я некоторое время использовал эти строки в своем файле инициализации, и это помогает сократить время запуска, не делая изменения постоянными:

;;;;; 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")))
blujay
источник
Почему ты не используешь after-init-hook?
Эрик
3
Потому что это запустится сразу после инициализации, что может заставить пользователя ждать GC. Используя таймер простоя, он может работать, когда пользователь не использует Emacs.
Блюджей