module Memprof:sig
..end
Memprof
是一个性能分析引擎,它随机采样分配的内存字。每个分配的字被采样的概率等于可配置的采样率。一旦一个块被采样,它就会被跟踪。被跟踪的块会在分配、提升或释放时触发用户定义的回调。
由于块由多个字组成,因此一个块可能会被多次采样。如果一个块被多次采样,则该块的每个事件都会调用一次回调:多重性在 allocation
结构的 n_samples
字段中给出。
此引擎使得可以将低开销内存分析器实现为 OCaml 库。
注意:此 API 为实验性 API。它可能会在未经事先通知的情况下更改。
type
t
配置文件的类型
type
allocation_source =
| |
普通 |
| |
序列化 |
| |
自定义 |
type
allocation = private {
|
n_samples : |
(* | 此块中的样本数(>= 1)。 | *) |
|
size : |
(* | 块的大小(以字为单位),不包括头部。 | *) |
|
source : |
(* | 分配的原因;从 OCaml 5 开始无法生成 | *) |
|
callstack : |
(* | 分配的调用栈。 | *) |
}
与分配关联的元数据类型。这是传递给由分配采样触发的回调的记录类型。
type ('minor, 'major)
tracker = {
|
alloc_minor : |
|
alloc_major : |
|
promote : |
|
dealloc_minor : |
|
dealloc_major : |
}
一个 ('minor, 'major) tracker
描述了 memprof 如何在其生命周期内跟踪采样块,为每个块保留用户定义的元数据:'minor
是为次要块保留的元数据类型,'major
是主要块的元数据类型。
tracker
中的成员函数称为回调函数。
如果分配或提升回调引发异常或返回 None
,则 memprof 将停止跟踪相应的块。
val null_tracker : ('minor, 'major) tracker
默认回调函数只返回 None
或 ()
val start : sampling_rate:float ->
?callstack_size:int -> ('minor, 'major) tracker -> t
使用给定的参数启动配置文件。如果当前域中已存在正在采样的配置文件,则引发异常。
采样立即开始。参数 sampling_rate
是每个字(包括头部)的采样率(样本数)。通常,如果回调函数开销较低,则 1e-4 的速率对性能没有明显影响,而 1e-3 会导致程序运行速度降低几个百分点。
参数 callstack_size
是每次采样时记录的调用栈长度。其默认值为 max_int
。
参数 tracker
确定如何在次要和主要堆中跟踪采样块的生命周期。
调用回调函数时,当前线程上的采样将暂时禁用,因此如果程序是单线程和单域的,则回调函数无需可重入。但是,如果使用线程或多个域,则可能会有多个回调函数并行运行。在这种情况下,回调函数必须是可重入的。
请注意,回调函数可能会在实际事件之后稍后被延迟调用。传递给分配回调函数的调用栈始终准确地反映分配,但程序状态可能在分配和对回调函数的调用之间发生了变化。
如果在性能分析处于活动状态时创建了新的线程或域,则子线程或域将加入该配置文件(使用相同的 sampling_rate
、callstack_size
和 tracker
回调函数)。
分配回调函数通常由分配块的线程运行。如果线程退出或配置文件在回调函数被调用之前停止,则回调函数可能会由不同的线程运行。
每个回调函数通常由分配块的域运行。如果域终止或配置文件在回调函数被调用之前停止,则回调函数可能会由不同的域运行。
不同的域可以同时运行不同的配置文件。
val stop : unit -> unit
停止当前配置文件的采样。如果当前域中没有正在采样的配置文件,则失败。停止所有共享该配置文件的线程和域的采样。
配置文件的回调函数可能会在调用 stop
后继续运行,直到对配置文件应用 discard
为止。
如果所有为其采样的域和线程都终止,则配置文件会隐式停止(但不会丢弃)。
val discard : t -> unit
丢弃已停止配置文件的所有性能分析状态,这将阻止任何更多回调函数。如果对尚未停止的配置文件调用,则引发异常。