module Gc: Gc
type
stat = {
|
minor_words : |
(* | 自程式啟動以來,在次要堆積中配置的字數。 | *) |
|
promoted_words : |
(* | 自程式啟動以來,在次要堆積中配置,並在次要回收後移動到主要堆積的字數。 | *) |
|
major_words : |
(* | 自程式啟動以來,在主要堆積中配置的字數,包括提升的字數。 | *) |
|
minor_collections : |
(* | 自程式啟動以來,次要回收的次數。 | *) |
|
major_collections : |
(* | 自程式啟動以來,完成的主要回收週期次數。 | *) |
|
heap_words : |
(* | 主要堆積的總大小,以字為單位。 | *) |
|
heap_chunks : |
(* | 構成主要堆積的連續記憶體區塊數量。此指標目前在 OCaml 5 中不可用:欄位值始終為 | *) |
|
live_words : |
(* | 主要堆積中存活資料的字數,包括標頭字。 請注意,「存活」字指的是主要堆積中每一個目前已知不可回收的字,其中包含在前一個垃圾回收週期開始後已變成程式無法存取的字。呼叫 | *) |
|
live_blocks : |
(* | 主要堆積中存活區塊的數量。 有關「存活」含義的注意事項,請參閱 | *) |
|
free_words : |
(* | 空閒清單中的字數。 | *) |
|
free_blocks : |
(* | 空閒清單中的區塊數量。此指標目前在 OCaml 5 中不可用:欄位值始終為 | *) |
|
largest_free : |
(* | 空閒清單中最大區塊的大小(以字為單位)。此指標目前在 OCaml 5 中不可用:欄位值始終為 | *) |
|
fragments : |
(* | 由於片段化而浪費的字數。這些是在兩個存活區塊之間放置的 1 個字的空閒區塊。它們無法用於配置。 | *) |
|
compactions : |
(* | 自程式啟動以來,堆積壓縮的次數。 | *) |
|
top_heap_words : |
(* | 主要堆積達到的最大大小(以字為單位)。 | *) |
|
stack_size : |
(* | 目前堆疊的大小(以字為單位)。此指標目前在 OCaml 5 中不可用:欄位值始終為
| *) |
|
forced_major_collections : |
(* | 自程式啟動以來,完成的強制完整主要回收次數。
| *) |
}
記憶體管理計數器會以 stat
記錄回傳。這些計數器會提供整個程式的值。
自程式啟動以來,程式配置的記憶體總量(以字為單位)為 minor_words + major_words - promoted_words
。乘以字元大小(32 位元機器為 4,64 位元機器為 8)即可取得位元組數。
type
control = {
|
minor_heap_size : |
(* | 次要堆積的大小(以字為單位)。變更此參數會觸發次要回收。此程式使用的次要堆積總大小是作用中網域的堆積大小總和。預設值:256k。 | *) |
|
major_heap_increment : |
(* | 在增加主要堆積時,要增加多少。如果此數字小於或等於 1000,則它是目前堆積大小的百分比(即,設定為 100 會使每次增加時堆積大小加倍)。如果它大於 1000,則它是要加入堆積的固定字數。預設值:15。 | *) |
|
space_overhead : |
(* | 主要垃圾回收速度是根據此參數計算的。這是將被「浪費」的記憶體,因為垃圾回收不會立即回收無法存取的區塊。它表示為用於存活資料的記憶體百分比。如果 | *) |
|
verbose : |
(* | 此值會控制標準錯誤輸出上的垃圾回收訊息。它是下列某些旗標的總和,可在對應的事件上列印訊息
| *) |
|
max_overhead : |
(* | 當估計的「浪費」記憶體量超過存活資料量的 | *) |
|
stack_limit : |
(* | 光纖堆疊的最大大小(以字為單位)。預設值:1024k。 | *) |
|
allocation_policy : |
(* | 用於在主要堆積中配置的原則。 在 OCaml 5.x 中會忽略此選項。 在 OCaml 5.0 之前,可能的值為 0、1 和 2。
| *) |
|
window_size : |
(* | 主要垃圾回收用於平滑其工作負載變化的視窗大小。這是一個介於 1 到 50 之間的整數。預設值:1。
| *) |
|
custom_major_ratio : |
(* | 位於主要堆積中的自訂值所持有的堆外記憶體之浮動垃圾對主要堆積大小的目標比率。會調整垃圾回收速度,以嘗試將這麼多記憶體用於尚未回收的死值。表示為主要堆積大小的百分比。預設值會使堆外浮動垃圾的大小與堆內額外負荷的大小大致相同。注意:這僅適用於使用
| *) |
|
custom_minor_ratio : |
(* | 位於次要堆積中的自訂值所持有的堆外記憶體之浮動垃圾界限。當次要堆積中的自訂值持有這麼多記憶體時,會觸發次要垃圾回收。表示為次要堆積大小的百分比。注意:這僅適用於使用
| *) |
|
custom_minor_max_size : |
(* | 針對在次要堆積中配置的每個自訂值,堆外記憶體的最大量。持有超過此位元組數的自訂值會配置在主要堆積上。注意:這僅適用於使用
| *) |
}
垃圾回收參數會以 control
記錄的形式提供。請注意,這些參數也可以透過設定 OCAMLRUNPARAM 環境變數來初始化。請參閱 ocamlrun
的文件。
val stat : unit -> stat
在代表程式總記憶體統計資料的 stat
記錄中,傳回記憶體管理計數器的目前值。此函式會導致完整的主要回收。
val quick_stat : unit -> stat
與 stat
相同,不同之處在於 live_words
、live_blocks
、free_words
、free_blocks
、largest_free
和 fragments
設定為 0。由於每個網域的緩衝區,它可能只代表自上次次要回收或主要週期以來程式總記憶體使用量的狀態。此函式比 stat
快得多,因為它不需要觸發完整的主要回收。
val counters : unit -> float * float * float
針對目前網域或可能是先前的網域,傳回 (minor_words, promoted_words, major_words)
。此函式與 quick_stat
一樣快。
val minor_words : unit -> float
此域或可能先前的域在次要堆積中配置的字詞數量。此數字在位元組碼程式中是準確的,但在編譯為原生碼的程式中僅為近似值。
在原生碼中,此函式不會進行配置。
val get : unit -> control
以 control
記錄的形式傳回 GC 參數的目前值。
val set : control -> unit
set r
會根據 control
記錄 r
變更 GC 參數。一般用法為:Gc.set { (Gc.get()) with Gc.verbose = 0x00d }
val minor : unit -> unit
觸發次要收集。
val major_slice : int -> int
major_slice n
執行次要收集和主要收集的一部分。n
是區塊大小:GC 會執行足夠的工作以釋放(平均)n
個字詞的記憶體。如果 n
= 0,GC 將嘗試執行足夠的工作以確保下一個自動區塊沒有任何工作要做。此函式傳回未指定的整數(目前:0)。
val major : unit -> unit
執行次要收集並完成目前的主要收集週期。
val full_major : unit -> unit
執行次要收集、完成目前的主要收集週期,並執行一個全新的完整週期。這將會收集所有目前無法存取的區塊。
val compact : unit -> unit
執行完整的主要收集並壓縮堆積。請注意,堆積壓縮是一項耗時的操作。
val print_stat : out_channel -> unit
將記憶體管理計數器的目前值(以人類可讀的形式)列印到總程式的通道引數中。
val allocated_bytes : unit -> float
傳回此域以及可能先前域所配置的位元組數。它以 float
的形式傳回,以避免 32 位元機器上 int
的溢位問題。
val get_minor_free : unit -> int
傳回此域次要堆積內可用空間的目前大小。
val finalise : ('a -> unit) -> 'a -> unit
finalise f v
將 f
註冊為 v
的最終化函式。v
必須是堆積配置的。f
會在 v
第一次變成無法存取(包括透過弱指標)與 GC 收集 v
之間,以 v
作為引數被呼叫。可以為相同的值註冊多個函式,甚至是同一個函式的多個執行個體。每個執行個體都會被呼叫一次(如果程式在 v
變成無法存取之前終止,則永遠不會被呼叫)。
GC 將會按照釋放順序呼叫最終化函式。當多個值同時變得無法存取時(也就是在同一個 GC 週期中),最終化函式將按照對應的 finalise
呼叫的反向順序被呼叫。如果 finalise
的呼叫順序與值的配置順序相同,這表示每個值都會在它所依賴的值之前最終化。當然,如果透過指派引入其他相依性,則此說法會失效。
在有多個 OCaml 執行緒的情況下,應該假設任何特定的最終化函式都可能會在任何執行緒中執行。
從最終化函式的閉包中可以存取的所有內容都被視為可存取的,因此以下程式碼將不會如預期般運作
let v = ... in Gc.finalise (fun _ -> ...v...) v
您應該確保 v
不在最終化函式的閉包中,而是撰寫
let f = fun x -> ... let v = ... in Gc.finalise f v
f
函式可以使用 OCaml 的所有功能,包括使值再次變成可存取的指派。它也可以永遠迴圈(在這種情況下,其他最終化函式不會在 f 的執行期間被呼叫,除非它呼叫 finalise_release
)。它可以針對 v
或其他值呼叫 finalise
以註冊其他函式,甚至是它本身。它可以引發例外狀況;在這種情況下,當函式被呼叫時,例外狀況會中斷程式正在執行的任何動作。
如果 v
無法保證是堆積配置的,finalise
會引發 Invalid_argument
。一些不是堆積配置的值的範例包括整數、常數建構函式、布林值、空陣列、空清單、單位值。哪些內容是堆積配置的確切清單是與實作相關的。某些常數值可以是堆積配置的,但在程式的生命週期內永遠不會釋放,例如整數常數的清單;這也是與實作相關的。請注意,類型為 float
的值有時會配置,有時不會,因此對它們進行最終化是不安全的,並且 finalise
也會對它們引發 Invalid_argument
。類型為 'a Lazy.t
(對於任何 'a
)的值在這方面與 float
類似,只是編譯器有時會以一種方式最佳化它們,從而阻止 finalise
偵測它們。在這種情況下,它不會引發 Invalid_argument
,但您仍應避免對惰性值呼叫 finalise
。
呼叫 String.make
、Bytes.make
、Bytes.create
、Array.make
和 ref
的結果保證是堆積配置且非常數的,除非長度引數為 0
。
val finalise_last : (unit -> unit) -> 'a -> unit
與 Gc.finalise
相同,只是該值未作為引數提供。因此,您無法使用給定的值來計算最終化函式。好處是該函式是在該值最後一次無法存取後而不是第一次無法存取後被呼叫。因此,與 Gc.finalise
相反,該值永遠不會再次變成可存取或再次被使用。特別是,所有包含此值作為索引鍵或資料的弱指標和臨時物件,都會在執行最終化函式之前被取消設定。此外,使用 Gc.finalise
附加的最終化函式始終會在使用 Gc.finalise_last
附加的最終化函式之前被呼叫。
val finalise_release : unit -> unit
最終化函式可能會呼叫 finalise_release
來告知 GC,它可以啟動下一個最終化函式,而無需等待目前函式傳回。
type
alarm
警示是在主要 GC 週期結束時呼叫使用者函式的一段資料。提供以下函式來建立和刪除警示。
val create_alarm : (unit -> unit) -> alarm
create_alarm f
將會安排在主要 GC 週期結束時呼叫 f
,該週期並非由 f
本身引起,從目前的週期或下一個週期開始。f
將在建立警示的同一域上執行,直到該域結束或呼叫 delete_alarm
為止。傳回類型為 alarm
的值,您可以使用該值來呼叫 delete_alarm
。
無法保證 Gc 警示會在每個主要 GC 週期結束時執行,但保證它最終會執行。
例如,以下是一種粗略的方法來中斷函式,如果程式的記憶體消耗超過給定的 MB limit
,則適用於在頂層使用
let run_with_memory_limit (limit : int) (f : unit -> 'a) : 'a =
let limit_memory () =
let mem = Gc.(quick_stat ()).heap_words in
if mem / (1024 * 1024) > limit / (Sys.word_size / 8) then
raise Out_of_memory
in
let alarm = Gc.create_alarm limit_memory in
Fun.protect f ~finally:(fun () -> Gc.delete_alarm alarm ; Gc.compact ())
val delete_alarm : alarm -> unit
delete_alarm a
將會停止呼叫與 a
關聯的函式。再次呼叫 delete_alarm a
沒有任何效果。
val eventlog_pause : unit -> unit
val eventlog_resume : unit -> unit
module Memprof:sig
..end
Memprof
是一個剖析引擎,會隨機取樣配置的記憶體字詞。