emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Larger GC thresholds for non-interactive Emacs (was: Org mode and Emacs)


From: Ihor Radchenko
Subject: Larger GC thresholds for non-interactive Emacs (was: Org mode and Emacs)
Date: Fri, 17 Jun 2022 15:18:21 +0800

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> thus Eli's choice is very good, and we really should do something about 
>>> that GC of ours.
>>
>> I am wondering if there is a "universal" value suitable for one-off Emacs
>> batch invocations.
>
> I doubt that's the case, but of course we should try and use values that
> work "overall best" on average.  Maybe we should revisit the current
> knobs and their default values.
>
> Currently the two important knobs we have are:
>
>     gc-cons-threshold
>     gc-cons-percentage
>
> Maybe it's time for some benchmarks with various values for these knobs
> to see if the values we're using now are "good enough" or might need to
> be changed.

Note that I did not initially ask to change the GC defaults for normal
Emacs session.

What I am trying to suggest is:
1. Have some conservative GC settings in interactive Emacs session (as
   we do now; I do _not_ suggest changing it)
2. Increase GC thresholds in non-interactive --batch sessions, which
   tend to not run for a long time.

I am a bit afraid to touch the topic of changing the interactive GC
defaults. People tend to have contradicting opinions on this.

I'd like to ask one thing from the very beginning here: Please spin a
separate thread if you have objections on actual GC defaults applicable
to normal Emacs sessions.

> We could also try and be bit more discerning.  E.g. currently when the
> program is in a phase where it builds a lot of new data-structures, we
> run the GC everytime some amount of new memory has been allocated, but
> presumably almost none of those objects have died yet (we're still
> building the overall datastructure) so the GC will be a pure waste of
> time.  OTOH in other phases the code allocates objects which are used
> only temporarily, in which case it's beneficial to run the GC somewhat
> frequently to avoid growing our heap unnecessarily (and suffering
> fragmentation as a result).

AFAIK, there is no way to determine such stage automatically. It's
usually up to the program. For example, org-element-parse-buffer
(function that creates buffer AST in Org) does the following:

(let (... (gc-cons-threshold #x40000000))
      ...
      (org-element--parse-elements ...))

A possible useful thing Emacs could help with would be a macro dedicated
to let-binds like the above. Something like:

(with-reduced-gc
 ;; Do staff)

 with-reduced-gc could take care about determining the inner specifics
 on what alternative gc-cons-threshold value should be used (possibly
 depending on the system memory information).

> It's hard to know beforehand whether a GC will be useful or not, tho.
> But maybe we can find good heuristics.  E.g. have something like
> a `gc-cons-percentage` which depends on how much garbage we collected in
> the last GC: if a GC doesn't collect any garbage (or very little of it),
> it's a sign that we're in a phase where running the GC is not very
> useful so we should wait a bit more until the next GC, whereas if the GC
> collected a fair bit of garbage, it's a sign that we're in a phase where
> running the GC is beneficial and we can run it a bit more often.

FYI, I have played with this approach making use of
https://gitlab.com/koral/gcmh

In practice, relying on recent GC history is often misleading.

GC is normally not very frequent - tens of seconds to minutes. And the
practical Emacs memory usage patterns are often irregular: long periods
of "idleness"/low intensity usage vs. short bursts of high memory
allocations when some "heavy" commands are called.

The adjustment you propose will suffer from the following:
1. There is long "idle" period and GC gets less frequent
2. User runs "heavy" command, GC frequency not yet adjusted
3. Command allocates a lots of memory - GC is finally triggered and has
   to go through a lot of garbage; It often happens _after_ the command
   finishes.
4. GC re-adjusts the frequency, but Emacs is again "idle" with no
   "heavy" commands being used.

Best,
Ihor



reply via email to

[Prev in Thread] Current Thread [Next in Thread]