Async's analog of Core_kernel.Gc
.
We remove the Expert
module, which has functions that are superseded by
Async-friendly functions below.
include module type of Core_kernel.Gc with module Gc.Expert := Core_kernel.Gc.Expert
This is a wrapper around INRIA's standard Gc
module. Provides memory
management control and statistics, and finalized values.
module Stat = Core_kernel.Gc.Stat
The memory management counters are returned in a stat
record.
The total amount of memory allocated by the program since it was started
is (in words) minor_words + major_words - promoted_words
. Multiply by
the word size (4 on a 32-bit machine, 8 on a 64-bit machine) to get
the number of bytes.
module Control = Core_kernel.Gc.Control
The GC parameters are given as a control
record.
Note that these parameters can also be initialised
by setting the OCAMLRUNPARAM environment variable.
See the documentation of ocamlrun.
external stat : Core_kernel__.Import.unit ‑> stat = "caml_gc_stat"
Return the current values of the memory management counters in a
stat
record. This function examines every heap block to get the
statistics.
external quick_stat : Core_kernel__.Import.unit ‑> stat = "caml_gc_quick_stat"
Same as stat
except that live_words
, live_blocks
, free_words
,
free_blocks
, largest_free
, and fragments
are set to 0. This
function is much faster than stat
because it does not need to go
through the heap.
external counters : Core_kernel__.Import.unit ‑> Core_kernel__.Import.float * Core_kernel__.Import.float * Core_kernel__.Import.float = "caml_gc_counters"
Return (minor_words, promoted_words, major_words)
. This function
is as fast at quick_stat
.
external minor_words : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_minor_words"
The following functions return the same as (Gc.quick_stat ()).Stat.f
, avoiding any
allocation (of the stat
record or a float). On 32-bit machines the int
may
overflow.
Note that minor_words
does not allocate, but we do not annotate it as noalloc
because we want the compiler to save the value of the allocation pointer register
(%r15 on x86-64) to the global variable caml_young_ptr
before the C stub tries to
read its value.
external major_words : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_major_words"
external promoted_words : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_promoted_words"
external minor_collections : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_minor_collections"
external major_collections : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_major_collections"
external heap_words : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_heap_words"
external heap_chunks : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_heap_chunks"
external compactions : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_compactions"
external top_heap_words : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_top_heap_words"
external major_plus_minor_words : Core_kernel__.Import.unit ‑> Core_kernel__.Import.int = "core_kernel_gc_major_plus_minor_words"
This function returns major_words () + minor_words ()
. It exists purely for speed
(one call into C rather than two). Like major_words
and minor_words
,
major_plus_minor_words
avoids allocating a stat
record or a float, and may
overflow on 32-bit machines.
This function is not marked [@@noalloc]
to ensure that the allocation pointer is
up-to-date when the minor-heap measurement is made.
external get : Core_kernel__.Import.unit ‑> control = "caml_gc_get"
Return the current values of the GC parameters in a control
record.
external set : control ‑> Core_kernel__.Import.unit = "caml_gc_set"
set r
changes the GC parameters according to the control
record r
.
The normal usage is:
Gc.set { (Gc.get()) with Gc.Control.verbose = 0x00d }
external minor : Core_kernel__.Import.unit ‑> Core_kernel__.Import.unit = "caml_gc_minor"
Trigger a minor collection.
external major_slice : Core_kernel__.Import.int ‑> Core_kernel__.Import.int = "caml_gc_major_slice"
Do a minor collection and a slice of major collection. The argument is the size of the slice, 0 to use the automatically-computed slice size. In all cases, the result is the computed slice size.
external major : Core_kernel__.Import.unit ‑> Core_kernel__.Import.unit = "caml_gc_major"
Do a minor collection and finish the current major collection cycle.
external full_major : Core_kernel__.Import.unit ‑> Core_kernel__.Import.unit = "caml_gc_full_major"
Do a minor collection, finish the current major collection cycle, and perform a complete new cycle. This will collect all currently unreachable blocks.
external compact : Core_kernel__.Import.unit ‑> Core_kernel__.Import.unit = "caml_gc_compaction"
Perform a full major collection and compact the heap. Note that heap compaction is a lengthy operation.
val print_stat : Pervasives.out_channel ‑> Core_kernel__.Import.unit
Print the current values of the memory management counters (in human-readable form) into the channel argument.
val allocated_bytes : Core_kernel__.Import.unit ‑> Core_kernel__.Import.float
Return the total number of bytes allocated since the program was
started. It is returned as a float
to avoid overflow problems
with int
on 32-bit machines.
val keep_alive : _ ‑> Core_kernel__.Import.unit
keep_alive a
ensures that a
is live at the point where keep_alive a
is called.
It is like ignore a
, except that the compiler won't be able to simplify it and
potentially collect a
too soon.
val tune : ?logger:(Core_kernel__.Import.string ‑> Core_kernel__.Import.unit) ‑> ?minor_heap_size:Core_kernel__.Import.int ‑> ?major_heap_increment:Core_kernel__.Import.int ‑> ?space_overhead:Core_kernel__.Import.int ‑> ?verbose:Core_kernel__.Import.int ‑> ?max_overhead:Core_kernel__.Import.int ‑> ?stack_limit:Core_kernel__.Import.int ‑> ?allocation_policy:Core_kernel__.Import.int ‑> ?window_size:Core_kernel__.Import.int ‑> Core_kernel__.Import.unit ‑> Core_kernel__.Import.unit
Adjust the specified GC parameters.
module Allocation_policy = Core_kernel.Gc.Allocation_policy
The policy used for allocating in the heap.
val disable_compaction : ?logger:(Core_kernel__.Import.string ‑> Core_kernel__.Import.unit) ‑> allocation_policy:[ `Don't_change | `Set_to of Allocation_policy.t ] ‑> Core_kernel__.Import.unit ‑> Core_kernel__.Import.unit
module Expert = Core_kernel.Gc.Expert
The Expert
module contains functions that novice users should not use, due to their
complexity.
val add_finalizer : 'a Core_kernel.Heap_block.t ‑> ('a Core_kernel.Heap_block.t ‑> unit) ‑> unit
add_finalizer b f
ensures that f
runs after b
becomes unreachable. f b
will
run in its own Async job. If f
raises, the unhandled exception will be raised to
the monitor that called add_finalizer b f
.
The OCaml runtime only supports finalizers on heap blocks, hence add_finalizer
requires b : _ Heap_block.t
. add_finalizer_exn b f
is like add_finalizer
, but
will raise if b
is not a heap block.
The runtime essentially maintains a set of finalizer pairs:
'a Heap_block.t * ('a Heap_block.t -> unit)
Each call to add_finalizer
adds a new pair to the set. It is allowed for many pairs
to have the same heap block, the same function, or both. Each pair is a distinct
element of the set.
After a garbage collection determines that a heap block b
is unreachable, it removes
from the set of finalizers all finalizer pairs (b, f)
whose block is b
, and then
and runs f b
for all such pairs. Thus, a finalizer registered with add_finalizer
will run at most once.
In a finalizer pair (b, f)
, it is a mistake for the closure of f
to reference
(directly or indirectly) b
-- f
should only access b
via its argument.
Referring to b
in any other way will cause b
to be kept alive forever, since f
itself is a root of garbage collection, and can itself only be collected after the
pair (b, f)
is removed from the set of finalizers.
The f
function can use all features of OCaml and Async, since it runs as an ordinary
Async job. f
can even make make b
reachable again. It can even call
add_finalizer
on b
or other values to register other finalizer functions.
val add_finalizer_last : 'a Core_kernel.Heap_block.t ‑> (unit ‑> unit) ‑> unit
Same as add_finalizer except that the function is not called until the value has become unreachable for the last time. This means that the finalization function does not recieve the value as an argument. Every weak pointer and ephemeron that contained this value as key or data is unset before running the finalization function.