add info on incremental GC mode to the Guide

This commit is contained in:
Matthew Flatt 2015-11-28 11:55:43 -07:00
parent 9407afa0a2
commit c9e9b4e400

View File

@ -471,7 +471,7 @@ then the expansion of the @racket[let] form to implement
automatically converts the closure to pass itself @racket[n] as an
argument instead.
@section{Reachability and Garbage Collection}
@section[#:tag "Reachability and Garbage Collection"]{Reachability and Garbage Collection}
In general, Racket re-uses the storage for a value when the
garbage collector can prove that the object is unreachable from
@ -534,7 +534,7 @@ There are a number of exceptions, however:
@item{Interned symbols are allocated only once (per place). A table inside
Racket tracks this allocation so a symbol may not become garbage
because that table holds onto it.}
@item{Reachability is only approximate with the CGC collector (i.e.,
@item{Reachability is only approximate with the @tech{CGC} collector (i.e.,
a value may appear reachable to that collector when there is,
in fact, no way to reach it anymore.}]
@ -577,3 +577,60 @@ occurrence of the variable @racket[_fishes]. That constitutes
a reference to the list, ensuring that the list is not itself
garbage collected, and thus the red fish is not either.
@section{Reducing Garbage Collection Pauses}
By default, Racket's @tech{generational garbage collector} creates
brief pauses for frequent @deftech{minor collections}, which inspect
only the most recently allocated objects, and long pauses for infrequent
@deftech{major collections}, which re-inspect all memory. Weak
references (as described in
@secref["Reachability\x20and\x20Garbage\x20Collection"]) are cleared
only by a major collection.
For soft real-time applications, such as animations, games, and some
network services, long pauses due to a major collection can interfere
unacceptably with a program's operation. To reduce major-collection
pauses, the Racket garbage collector supports @deftech{incremental
garbage-collection} mode. In incremental mode, minor collections
create longer (but still relatively short) pauses by performing extra
work toward the next major collection. If all goes well, most of a
major collection's work has been performed by minor collections the
time that a major collection is needed, so the major collection's
pause is as short as a minor collection's pause. Incremental mode
tends to use more memory and run more slowly overall, but it can
provide much more consistent real-time behavior.
If the @envvar{PLT_INCREMENTAL_GC} environment variable is set when
Racket starts, incremental mode is permanently enabled. Since
incremental mode is only useful for certain parts of some programs,
however, and since the need for incremental mode is a property of a
program rather than its environment, the preferred way to enable
incremental mode is with @racket[(collect-garbage 'incremental)].
Calling @racket[(collect-garbage 'incremental)] does not perform an
immediate garbage collection, but instead requests that each minor
collection perform incremental work up to the next major collection.
The request expires with the next major collection. Make a call to
@racket[(collect-garbage 'incremental)] in any periodic task within
an application that needs to be responsive in real time.
To check whether incremental mode is use and how it affects pause
times, enable @tt{debug}-level logging output for the
@racketidfont{GC} topic. For example,
@commandline{racket -W "debuG@"@"GC error" main.rkt}
runs @filepath{main.rkt} with garbage-collection logging to stderr
(while preserving @tt{error}-level logging for all topics). Minor
collections are reported by @litchar{min} lines, increment-mode minor
collection are reported with @litchar{mIn} lines, and major
collections are reported with @litchar{MAJ} lines.
Some Racket features can interfere with incremental mode. In
particular, memory accounting via @racket[custodian-limit-memory]
triggers an accounting pass during a major collection, and that pass
is not currently incremental. Note that DrRacket uses
@racket[custodian-limit-memory] to control the memory use of programs
run within DrRacket, so incremental mode is useful mainly outside of
DrRacket. (See also @secref["DrRacket-perf"].)