.TH "Gc" 3 2024-05-31 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\&. This metrics is currently not available in OCaml 5: the field value is always .ft B 0 .ft R \&. *) 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\&. This metrics is currently not available in OCaml 5: the field value is always .ft B 0 .ft R \&. *) largest_free : .B int ; (* Size (in words) of the largest block in the free list\&. This metrics is currently not available in OCaml 5: the field value is always .ft B 0 .ft R \&. *) 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\&. This metrics is currently not available in OCaml 5: the field value is always .ft B 0 .ft R \&. .sp .B "Since" 3.12 *) forced_major_collections : .B int ; (* Number of forced full major collections completed since the program was started\&. .sp .B "Since" 4.12 *) } .sp The memory management counters are returned in a .ft B stat .ft R record\&. These counters give values for the whole program\&. .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 = { minor_heap_size : .B int ; (* The size (in words) of the minor heap\&. Changing this parameter will trigger a minor collection\&. The total size of the minor heap used by this program is the sum of the heap sizes of the active domains\&. Default: 256k\&. *) 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\&. *) 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\&. *) 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\&. *) 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\&. Default: 500\&. *) stack_limit : .B int ; (* The maximum size of the fiber stacks (in words)\&. Default: 1024k\&. *) allocation_policy : .B int ; (* The policy used for allocating in the major heap\&. .sp This option is ignored in OCaml 5\&.x\&. .sp Prior to OCaml 5\&.0, possible values were 0, 1 and 2\&. .sp .sp \-0 was the next\-fit policy .sp \-1 was the first\-fit policy (since OCaml 3\&.11) .sp \-2 was the best\-fit policy (since OCaml 4\&.10) .sp .B "Since" 3.11 *) 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 *) 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 *) 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 *) custom_minor_max_size : .B int ; (* Maximum amount of out\-of\-heap memory for each custom value allocated in the minor heap\&. Custom values that hold more than this many bytes are allocated on the major heap\&. Note: this only applies to values allocated with .ft B caml_alloc_custom_mem .ft R (e\&.g\&. bigarrays)\&. Default: 70000 bytes\&. .sp .B "Since" 4.08 *) } .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 that represent the program\&'s total memory stats\&. This function causes a full major collection\&. .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\&. Due to per\-domain buffers it may only represent the state of the program\&'s total memory usage since the last minor collection or major cycle\&. This function is much faster than .ft B stat .ft R because it does not need to trigger a full major collection\&. .sp .I val counters : .B unit -> float * float * float .sp Return .ft B (minor_words, promoted_words, major_words) .ft R for the current domain or potentially previous domains\&. 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 by this domain or potentially previous domains\&. 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 .B Alert unsynchronized_access. GC parameters are a mutable global state. .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 .B Alert unsynchronized_access. GC parameters are a mutable global state. .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) of the total program into the channel argument\&. .sp .I val allocated_bytes : .B unit -> float .sp Return the number of bytes allocated by this domain and potentially a previous domain\&. 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 of this domain\&. .sp .B "Since" 4.03 .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 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 major GC cycles, not caused by .ft B f .ft R itself, starting with the current cycle or the next one\&. .ft B f .ft R will run on the same domain that created the alarm, until the domain exits or .ft B delete_alarm .ft R is called\&. A value of type .ft B alarm .ft R is returned that you can use to call .ft B delete_alarm .ft R \&. .sp It is not guaranteed that the Gc alarm runs at the end of every major GC cycle, but it is guaranteed that it will run eventually\&. .sp As an example, here is a crude way to interrupt a function if the memory consumption of the program exceeds a given .ft B limit .ft R in MB, suitable for use in the toplevel: .sp .EX .ft B .br \&let run_with_memory_limit (limit : int) (f : unit \-> \&'a) : \&'a = .br \& let limit_memory () = .br \& let mem = Gc\&.(quick_stat ())\&.heap_words in .br \& if mem / (1024 * 1024) > limit / (Sys\&.word_size / 8) then .br \& raise Out_of_memory .br \& in .br \& let alarm = Gc\&.create_alarm limit_memory in .br \& Fun\&.protect f ~finally:(fun () \-> Gc\&.delete_alarm alarm ; Gc\&.compact ()) .br \& .ft R .EE .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 .B "Deprecated." Use Runtime_events\&.pause instead\&. .sp .I val eventlog_resume : .B unit -> unit .sp .B "Deprecated." Use Runtime_events\&.resume instead\&. .sp .I module Memprof : .B sig end .sp .ft B Memprof .ft R is a profiling engine which randomly samples 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 callbacks 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