.TH "Gc.Memprof" 3 2024-05-31 OCamldoc "OCaml library" .SH NAME Gc.Memprof \- Memprof is a profiling engine which randomly samples allocated memory words. .SH Module Module Gc.Memprof .SH Documentation .sp Module .BI "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 .sp .sp .I type t .sp the type of a profile .sp .I type allocation_source = | Normal | Marshal | Custom .sp .sp .I type allocation = private { n_samples : .B int ; (* The number of samples in this block (>= 1)\&. *) size : .B int ; (* The size of the block, in words, excluding the header\&. *) source : .B allocation_source ; (* The cause of the allocation; .ft B Marshal .ft R cannot be produced since OCaml 5\&. *) callstack : .B Printexc.raw_backtrace ; (* The callstack for the allocation\&. *) } .sp The type of metadata associated with allocations\&. This is the type of records passed to the callback triggered by the sampling of an allocation\&. .sp .I type .B ('minor, 'major) .I tracker = { alloc_minor : .B allocation -> 'minor option ; alloc_major : .B allocation -> 'major option ; promote : .B 'minor -> 'major option ; dealloc_minor : .B 'minor -> unit ; dealloc_major : .B 'major -> unit ; } .sp A .ft B (\&'minor, \&'major) tracker .ft R describes how memprof should track sampled blocks over their lifetime, keeping a user\-defined piece of metadata for each of them: .ft B \&'minor .ft R is the type of metadata to keep for minor blocks, and .ft B \&'major .ft R the type of metadata for major blocks\&. .sp The member functions in a .ft B tracker .ft R are called callbacks\&. .sp If an allocation or promotion callback raises an exception or returns .ft B None .ft R , memprof stops tracking the corresponding block\&. .sp .I val null_tracker : .B ('minor, 'major) tracker .sp Default callbacks simply return .ft B None .ft R or .ft B () .ft R .sp .I val start : .B sampling_rate:float -> .B ?callstack_size:int -> ('minor, 'major) tracker -> t .sp Start a profile with the given parameters\&. Raises an exception if a profile is already sampling in the current domain\&. .sp Sampling begins immediately\&. The parameter .ft B sampling_rate .ft R is the sampling rate in samples per word (including headers)\&. Usually, with cheap callbacks, a rate of 1e\-4 has no visible effect on performance, and 1e\-3 causes the program to run a few percent slower\&. .sp The parameter .ft B callstack_size .ft R is the length of the callstack recorded at every sample\&. Its default is .ft B max_int .ft R \&. .sp The parameter .ft B tracker .ft R determines how to track sampled blocks over their lifetime in the minor and major heap\&. .sp Sampling is temporarily disabled on the current thread when calling a callback, so callbacks do not need to be re\-entrant if the program is single\-threaded and single\-domain\&. However, if threads or multiple domains are used, it is possible that several callbacks will run in parallel\&. In this case, callback functions must be re\-entrant\&. .sp Note that a callback may be postponed slightly after the actual event\&. The callstack passed to an allocation callback always accurately reflects the allocation, but the program state may have evolved between the allocation and the call to the callback\&. .sp If a new thread or domain is created when profiling is active, the child thread or domain joins that profile (using the same .ft B sampling_rate .ft R , .ft B callstack_size .ft R , and .ft B tracker .ft R callbacks)\&. .sp An allocation callback is generally run by the thread which allocated the block\&. If the thread exits or the profile is stopped before the callback is called, the callback may be run by a different thread\&. .sp Each callback is generally run by the domain which allocated the block\&. If the domain terminates or the profile is stopped before the callback is called, the callback may be run by a different domain\&. .sp Different domains may run different profiles simultaneously\&. .sp .I val stop : .B unit -> unit .sp Stop sampling for the current profile\&. Fails if no profile is sampling in the current domain\&. Stops sampling in all threads and domains sharing the profile\&. .sp Callbacks from a profile may run after .ft B stop .ft R is called, until .ft B discard .ft R is applied to the profile\&. .sp A profile is implicitly stopped (but not discarded) if all domains and threads sampling for it are terminated\&. .sp .I val discard : .B t -> unit .sp Discards all profiling state for a stopped profile, which prevents any more callbacks for it\&. Raises an exception if called on a profile which has not been stopped\&. .sp