.TH "Gc" 3o 2023-09-18 OCamldoc "OCaml library" .SH NAME Gc \- Memory management control and statistics; finalised values. .SH Module Module Gc .SH Documentation .sp Module .BI "Gc" : .B sig end .sp Memory management control and statistics; finalised values\&. .sp .sp .sp .I type stat = { minor_words : .B float ; (* Number of words allocated in the minor heap since the program was started\&. *) promoted_words : .B float ; (* Number of words allocated in the minor heap that survived a minor collection and were moved to the major heap since the program was started\&. *) major_words : .B float ; (* Number of words allocated in the major heap, including the promoted words, since the program was started\&. *) minor_collections : .B int ; (* Number of minor collections since the program was started\&. *) major_collections : .B int ; (* Number of major collection cycles completed since the program was started\&. *) heap_words : .B int ; (* Total size of the major heap, in words\&. *) heap_chunks : .B int ; (* Number of contiguous pieces of memory that make up the major heap\&. *) live_words : .B int ; (* Number of words of live data in the major heap, including the header words\&. .sp Note that "live" words refers to every word in the major heap that isn\&'t currently known to be collectable, which includes words that have become unreachable by the program after the start of the previous gc cycle\&. It is typically much simpler and more predictable to call .ft B Gc\&.full_major .ft R (or .ft B Gc\&.compact .ft R ) then computing gc stats, as then "live" words has the simple meaning of "reachable by the program"\&. One caveat is that a single call to .ft B Gc\&.full_major .ft R will not reclaim values that have a finaliser from .ft B Gc\&.finalise .ft R (this does not apply to .ft B Gc\&.finalise_last .ft R )\&. If this caveat matters, simply call .ft B Gc\&.full_major .ft R twice instead of once\&. *) live_blocks : .B int ; (* Number of live blocks in the major heap\&. .sp See .ft B live_words .ft R for a caveat about what "live" means\&. *) free_words : .B int ; (* Number of words in the free list\&. *) free_blocks : .B int ; (* Number of blocks in the free list\&. *) largest_free : .B int ; (* Size (in words) of the largest block in the free list\&. *) fragments : .B int ; (* Number of wasted words due to fragmentation\&. These are 1\-words free blocks placed between two live blocks\&. They are not available for allocation\&. *) compactions : .B int ; (* Number of heap compactions since the program was started\&. *) top_heap_words : .B int ; (* Maximum size reached by the major heap, in words\&. *) stack_size : .B int ; (* Current size of the stack, in words\&. .sp .B "Since" 3.12.0 *) forced_major_collections : .B int ; (* Number of forced full major collections completed since the program was started\&. .sp .B "Since" 4.12.0 *) } .sp The memory management counters are returned in a .ft B stat .ft R record\&. .sp The total amount of memory allocated by the program since it was started is (in words) .ft B minor_words + major_words \- promoted_words .ft R \&. Multiply by the word size (4 on a 32\-bit machine, 8 on a 64\-bit machine) to get the number of bytes\&. .sp .I type control = { .B mutable minor_heap_size : .B int ; (* The size (in words) of the minor heap\&. Changing this parameter will trigger a minor collection\&. Default: 256k\&. *) .B mutable major_heap_increment : .B int ; (* How much to add to the major heap when increasing it\&. If this number is less than or equal to 1000, it is a percentage of the current heap size (i\&.e\&. setting it to 100 will double the heap size at each increase)\&. If it is more than 1000, it is a fixed number of words that will be added to the heap\&. Default: 15\&. *) .B mutable space_overhead : .B int ; (* The major GC speed is computed from this parameter\&. This is the memory that will be "wasted" because the GC does not immediately collect unreachable blocks\&. It is expressed as a percentage of the memory used for live data\&. The GC will work more (use more CPU time and collect blocks more eagerly) if .ft B space_overhead .ft R is smaller\&. Default: 120\&. *) .B mutable verbose : .B int ; (* This value controls the GC messages on standard error output\&. It is a sum of some of the following flags, to print messages on the corresponding events: .sp \- .ft B 0x001 .ft R Start and end of major GC cycle\&. .sp \- .ft B 0x002 .ft R Minor collection and major GC slice\&. .sp \- .ft B 0x004 .ft R Growing and shrinking of the heap\&. .sp \- .ft B 0x008 .ft R Resizing of stacks and memory manager tables\&. .sp \- .ft B 0x010 .ft R Heap compaction\&. .sp \- .ft B 0x020 .ft R Change of GC parameters\&. .sp \- .ft B 0x040 .ft R Computation of major GC slice size\&. .sp \- .ft B 0x080 .ft R Calling of finalisation functions\&. .sp \- .ft B 0x100 .ft R Bytecode executable and shared library search at start\-up\&. .sp \- .ft B 0x200 .ft R Computation of compaction\-triggering condition\&. .sp \- .ft B 0x400 .ft R Output GC statistics at program exit\&. Default: 0\&. *) .B mutable max_overhead : .B int ; (* Heap compaction is triggered when the estimated amount of "wasted" memory is more than .ft B max_overhead .ft R percent of the amount of live data\&. If .ft B max_overhead .ft R is set to 0, heap compaction is triggered at the end of each major GC cycle (this setting is intended for testing purposes only)\&. If .ft B max_overhead >= 1000000 .ft R , compaction is never triggered\&. If compaction is permanently disabled, it is strongly suggested to set .ft B allocation_policy .ft R to 2\&. Default: 500\&. *) .B mutable stack_limit : .B int ; (* The maximum size of the stack (in words)\&. This is only relevant to the byte\-code runtime, as the native code runtime uses the operating system\&'s stack\&. Default: 1024k\&. *) .B mutable allocation_policy : .B int ; (* The policy used for allocating in the major heap\&. Possible values are 0, 1 and 2\&. .sp .sp \-0 is the next\-fit policy, which is usually fast but can result in fragmentation, increasing memory consumption\&. .sp \-1 is the first\-fit policy, which avoids fragmentation but has corner cases (in certain realistic workloads) where it is sensibly slower\&. .sp \-2 is the best\-fit policy, which is fast and avoids fragmentation\&. In our experiments it is faster and uses less memory than both next\-fit and first\-fit\&. (since OCaml 4\&.10) The default is best\-fit\&. .sp On one example that was known to be bad for next\-fit and first\-fit, next\-fit takes 28s using 855Mio of memory, first\-fit takes 47s using 566Mio of memory, best\-fit takes 27s using 545Mio of memory\&. .sp Note: If you change to next\-fit, you may need to reduce the .ft B space_overhead .ft R setting, for example using .ft B 80 .ft R instead of the default .ft B 120 .ft R which is tuned for best\-fit\&. Otherwise, your program will need more memory\&. .sp Note: changing the allocation policy at run\-time forces a heap compaction, which is a lengthy operation unless the heap is small (e\&.g\&. at the start of the program)\&. .sp Default: 2\&. .sp .B "Since" 3.11.0 *) window_size : .B int ; (* The size of the window used by the major GC for smoothing out variations in its workload\&. This is an integer between 1 and 50\&. Default: 1\&. .sp .B "Since" 4.03.0 *) custom_major_ratio : .B int ; (* Target ratio of floating garbage to major heap size for out\-of\-heap memory held by custom values located in the major heap\&. The GC speed is adjusted to try to use this much memory for dead values that are not yet collected\&. Expressed as a percentage of major heap size\&. The default value keeps the out\-of\-heap floating garbage about the same size as the in\-heap overhead\&. Note: this only applies to values allocated with .ft B caml_alloc_custom_mem .ft R (e\&.g\&. bigarrays)\&. Default: 44\&. .sp .B "Since" 4.08.0 *) custom_minor_ratio : .B int ; (* Bound on floating garbage for out\-of\-heap memory held by custom values in the minor heap\&. A minor GC is triggered when this much memory is held by custom values located in the minor heap\&. Expressed as a percentage of minor heap size\&. Note: this only applies to values allocated with .ft B caml_alloc_custom_mem .ft R (e\&.g\&. bigarrays)\&. Default: 100\&. .sp .B "Since" 4.08.0 *) custom_minor_max_size : .B int ; (* Maximum amount of out\-of\-heap memory for each custom value allocated in the minor heap\&. When a custom value is allocated on the minor heap and holds more than this many bytes, only this value is counted against .ft B custom_minor_ratio .ft R and the rest is directly counted against .ft B custom_major_ratio .ft R \&. Note: this only applies to values allocated with .ft B caml_alloc_custom_mem .ft R (e\&.g\&. bigarrays)\&. Default: 8192 bytes\&. .sp .B "Since" 4.08.0 *) } .sp The GC parameters are given as a .ft B control .ft R record\&. Note that these parameters can also be initialised by setting the OCAMLRUNPARAM environment variable\&. See the documentation of .ft B ocamlrun .ft R \&. .sp .I val stat : .B unit -> stat .sp Return the current values of the memory management counters in a .ft B stat .ft R record\&. This function examines every heap block to get the statistics\&. .sp .I val quick_stat : .B unit -> stat .sp Same as .ft B stat .ft R except that .ft B live_words .ft R , .ft B live_blocks .ft R , .ft B free_words .ft R , .ft B free_blocks .ft R , .ft B largest_free .ft R , and .ft B fragments .ft R are set to 0\&. This function is much faster than .ft B stat .ft R because it does not need to go through the heap\&. .sp .I val counters : .B unit -> float * float * float .sp Return .ft B (minor_words, promoted_words, major_words) .ft R \&. This function is as fast as .ft B quick_stat .ft R \&. .sp .I val minor_words : .B unit -> float .sp Number of words allocated in the minor heap since the program was started\&. This number is accurate in byte\-code programs, but only an approximation in programs compiled to native code\&. .sp In native code this function does not allocate\&. .sp .B "Since" 4.04 .sp .I val get : .B unit -> control .sp Return the current values of the GC parameters in a .ft B control .ft R record\&. .sp .I val set : .B control -> unit .sp .ft B set r .ft R changes the GC parameters according to the .ft B control .ft R record .ft B r .ft R \&. The normal usage is: .ft B Gc\&.set { (Gc\&.get()) with Gc\&.verbose = 0x00d } .ft R .sp .I val minor : .B unit -> unit .sp Trigger a minor collection\&. .sp .I val major_slice : .B int -> int .sp .ft B major_slice n .ft R Do a minor collection and a slice of major collection\&. .ft B n .ft R is the size of the slice: the GC will do enough work to free (on average) .ft B n .ft R words of memory\&. If .ft B n .ft R = 0, the GC will try to do enough work to ensure that the next automatic slice has no work to do\&. This function returns an unspecified integer (currently: 0)\&. .sp .I val major : .B unit -> unit .sp Do a minor collection and finish the current major collection cycle\&. .sp .I val full_major : .B unit -> unit .sp Do a minor collection, finish the current major collection cycle, and perform a complete new cycle\&. This will collect all currently unreachable blocks\&. .sp .I val compact : .B unit -> unit .sp Perform a full major collection and compact the heap\&. Note that heap compaction is a lengthy operation\&. .sp .I val print_stat : .B out_channel -> unit .sp Print the current values of the memory management counters (in human\-readable form) into the channel argument\&. .sp .I val allocated_bytes : .B unit -> float .sp Return the total number of bytes allocated since the program was started\&. It is returned as a .ft B float .ft R to avoid overflow problems with .ft B int .ft R on 32\-bit machines\&. .sp .I val get_minor_free : .B unit -> int .sp Return the current size of the free space inside the minor heap\&. .sp .B "Since" 4.03.0 .sp .I val get_bucket : .B int -> int .sp .ft B get_bucket n .ft R returns the current size of the .ft B n .ft R \-th future bucket of the GC smoothing system\&. The unit is one millionth of a full GC\&. .sp .B "Since" 4.03.0 .sp .B "Raises Invalid_argument" if .ft B n .ft R is negative, return 0 if n is larger than the smoothing window\&. .sp .I val get_credit : .B unit -> int .sp .ft B get_credit () .ft R returns the current size of the "work done in advance" counter of the GC smoothing system\&. The unit is one millionth of a full GC\&. .sp .B "Since" 4.03.0 .sp .I val huge_fallback_count : .B unit -> int .sp Return the number of times we tried to map huge pages and had to fall back to small pages\&. This is always 0 if .ft B OCAMLRUNPARAM .ft R contains .ft B H=1 .ft R \&. .sp .B "Since" 4.03.0 .sp .I val finalise : .B ('a -> unit) -> 'a -> unit .sp .ft B finalise f v .ft R registers .ft B f .ft R as a finalisation function for .ft B v .ft R \&. .ft B v .ft R must be heap\-allocated\&. .ft B f .ft R will be called with .ft B v .ft R as argument at some point between the first time .ft B v .ft R becomes unreachable (including through weak pointers) and the time .ft B v .ft R is collected by the GC\&. Several functions can be registered for the same value, or even several instances of the same function\&. Each instance will be called once (or never, if the program terminates before .ft B v .ft R becomes unreachable)\&. .sp The GC will call the finalisation functions in the order of deallocation\&. When several values become unreachable at the same time (i\&.e\&. during the same GC cycle), the finalisation functions will be called in the reverse order of the corresponding calls to .ft B finalise .ft R \&. If .ft B finalise .ft R is called in the same order as the values are allocated, that means each value is finalised before the values it depends upon\&. Of course, this becomes false if additional dependencies are introduced by assignments\&. .sp In the presence of multiple OCaml threads it should be assumed that any particular finaliser may be executed in any of the threads\&. .sp Anything reachable from the closure of finalisation functions is considered reachable, so the following code will not work as expected: .sp \- .ft B let v = \&.\&.\&. in Gc\&.finalise (fun _ \-> \&.\&.\&.v\&.\&.\&.) v .ft R Instead you should make sure that .ft B v .ft R is not in the closure of the finalisation function by writing: .sp \- .ft B let f = fun x \-> \&.\&.\&. let v = \&.\&.\&. in Gc\&.finalise f v .ft R The .ft B f .ft R function can use all features of OCaml, including assignments that make the value reachable again\&. It can also loop forever (in this case, the other finalisation functions will not be called during the execution of f, unless it calls .ft B finalise_release .ft R )\&. It can call .ft B finalise .ft R on .ft B v .ft R or other values to register other functions or even itself\&. It can raise an exception; in this case the exception will interrupt whatever the program was doing when the function was called\&. .sp .ft B finalise .ft R will raise .ft B Invalid_argument .ft R if .ft B v .ft R is not guaranteed to be heap\-allocated\&. Some examples of values that are not heap\-allocated are integers, constant constructors, booleans, the empty array, the empty list, the unit value\&. The exact list of what is heap\-allocated or not is implementation\-dependent\&. Some constant values can be heap\-allocated but never deallocated during the lifetime of the program, for example a list of integer constants; this is also implementation\-dependent\&. Note that values of types .ft B float .ft R are sometimes allocated and sometimes not, so finalising them is unsafe, and .ft B finalise .ft R will also raise .ft B Invalid_argument .ft R for them\&. Values of type .ft B \&'a Lazy\&.t .ft R (for any .ft B \&'a .ft R ) are like .ft B float .ft R in this respect, except that the compiler sometimes optimizes them in a way that prevents .ft B finalise .ft R from detecting them\&. In this case, it will not raise .ft B Invalid_argument .ft R , but you should still avoid calling .ft B finalise .ft R on lazy values\&. .sp The results of calling .ft B String\&.make .ft R , .ft B Bytes\&.make .ft R , .ft B Bytes\&.create .ft R , .ft B Array\&.make .ft R , and .ft B ref .ft R are guaranteed to be heap\-allocated and non\-constant except when the length argument is .ft B 0 .ft R \&. .sp .I val finalise_last : .B (unit -> unit) -> 'a -> unit .sp same as .ft B Gc\&.finalise .ft R except the value is not given as argument\&. So you can\&'t use the given value for the computation of the finalisation function\&. The benefit is that the function is called after the value is unreachable for the last time instead of the first time\&. So contrary to .ft B Gc\&.finalise .ft R the value will never be reachable again or used again\&. In particular every weak pointer and ephemeron that contained this value as key or data is unset before running the finalisation function\&. Moreover the finalisation functions attached with .ft B Gc\&.finalise .ft R are always called before the finalisation functions attached with .ft B Gc\&.finalise_last .ft R \&. .sp .B "Since" 4.04 .sp .I val finalise_release : .B unit -> unit .sp A finalisation function may call .ft B finalise_release .ft R to tell the GC that it can launch the next finalisation function without waiting for the current one to return\&. .sp .I type alarm .sp An alarm is a piece of data that calls a user function at the end of each major GC cycle\&. The following functions are provided to create and delete alarms\&. .sp .I val create_alarm : .B (unit -> unit) -> alarm .sp .ft B create_alarm f .ft R will arrange for .ft B f .ft R to be called at the end of each major GC cycle, starting with the current cycle or the next one\&. A value of type .ft B alarm .ft R is returned that you can use to call .ft B delete_alarm .ft R \&. .sp .I val delete_alarm : .B alarm -> unit .sp .ft B delete_alarm a .ft R will stop the calls to the function associated to .ft B a .ft R \&. Calling .ft B delete_alarm a .ft R again has no effect\&. .sp .I val eventlog_pause : .B unit -> unit .sp .ft B eventlog_pause () .ft R will pause the collection of traces in the runtime\&. Traces are collected if the program is linked to the instrumented runtime and started with the environment variable OCAML_EVENTLOG_ENABLED\&. Events are flushed to disk after pausing, and no new events will be recorded until .ft B eventlog_resume .ft R is called\&. .sp .B "Since" 4.11 .sp .I val eventlog_resume : .B unit -> unit .sp .ft B eventlog_resume () .ft R will resume the collection of traces in the runtime\&. Traces are collected if the program is linked to the instrumented runtime and started with the environment variable OCAML_EVENTLOG_ENABLED\&. This call can be used after calling .ft B eventlog_pause .ft R , or if the program was started with OCAML_EVENTLOG_ENABLED=p\&. (which pauses the collection of traces before the first event\&.) .sp .B "Since" 4.11 .sp .I module Memprof : .B sig end .sp .ft B Memprof .ft R is a sampling engine for allocated memory words\&. Every allocated word has a probability of being sampled equal to a configurable sampling rate\&. Once a block is sampled, it becomes tracked\&. A tracked block triggers a user\-defined callback as soon as it is allocated, promoted or deallocated\&. .sp Since blocks are composed of several words, a block can potentially be sampled several times\&. If a block is sampled several times, then each of the callback is called once for each event of this block: the multiplicity is given in the .ft B n_samples .ft R field of the .ft B allocation .ft R structure\&. .sp This engine makes it possible to implement a low\-overhead memory profiler as an OCaml library\&. .sp Note: this API is EXPERIMENTAL\&. It may change without prior notice\&. .sp