Модуль Gc
module Gc: sig .. end
Управление памятью и статистика; окончательные значения.
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. Умножьте на размер слова (4 на 32-разрядной машине, 8 на 64-разрядной машине), чтобы получить количество байт.
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
Количество слов, выделенных в малом куске памяти этой областью или потенциально предыдущими областями. Это число точно в программах байткода, но только приблизительное в программах, скомпилированных в машинный код.
В программах машинного кода эта функция не выделяет память.
- Since 4.04
val get : unit -> control
Возвращает текущие значения параметров сборщика мусора в control записи.
- Предупреждение unsynchronized_access. Параметры сборщика мусора — это изменяемое глобальное состояние.
val set : control -> unit
set r изменяет параметры сборщика мусора в соответствии с control записью r. Обычное использование: Gc.set { (Gc.get()) with Gc.verbose = 0x00d }
- Предупреждение unsynchronized_access. Параметры сборщика мусора — это изменяемое глобальное состояние.
val minor : unit -> unit
Запустить сбор мусора малого размера.
val major_slice : int -> int
major_slice n Выполнить небольшую коллекцию и срез большой коллекции. n — размер среза: сборщик мусора выполнит достаточно работы, чтобы освободить (в среднем) n слов памяти. Если n = 0, сборщик мусора попытается выполнить достаточно работы, чтобы гарантировать, что следующий автоматический срез не потребует работы. Эта функция возвращает неопределённое целое число (в настоящее время: 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 для предотвращения проблем переполнения с int на 32-разрядных машинах.
val get_minor_free : unit -> int
Возвращает текущий размер свободного места внутри меньшей кучи этой области.
- Since 4.03
val finalise : ('a -> unit) -> 'a -> unit
finalise f v регистрирует f как функцию завершения для v. v должна быть выделена в куче. f будет вызвана с v в качестве аргумента в какой-то момент между первым временем, когда v становится недостижимой (включая через слабые ссылки) и временем, когда v собирается сборщиком мусора. Для одного значения могут быть зарегистрированы несколько функций, или даже несколько экземпляров одной функции. Каждый экземпляр будет вызван один раз (или никогда, если программа завершится до того, как v станет недостижимой).
Сборщик мусора вызовет функции завершения в порядке освобождения. Когда несколько значений становятся недостижимыми одновременно (т.е. во время одного цикла сборки мусора), функции завершения будут вызваны в обратном порядке соответствующих вызовов 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). Она может вызывать finalise на v или других значениях, чтобы зарегистрировать другие функции или даже себя. Она может вызвать исключение; в этом случае исключение прервёт всё, что делала программа, когда функция была вызвана.
finalise вызовет Invalid_argument, если v не гарантированно выделяется в куче. Некоторые примеры значений, которые не выделяются в куче, — это целые числа, константные конструкторы, булевы значения, пустой массив, пустой список, единичное значение. Точный список того, что выделяется в куче, а что нет, зависит от реализации. Некоторые константные значения могут быть выделены в куче, но никогда не освобождаться за время жизни программы, например, список константных целых чисел; это также зависит от реализации. Обратите внимание, что значения типов 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.
- Since 4.04
val finalise_release : unit -> unit
Функция завершения может вызвать finalise_release чтобы сообщить сборщику мусора, что он может запустить следующую функцию завершения, не ожидая возвращения текущей.
type alarm
Предупреждение — это данные, которые вызывают пользовательскую функцию в конце цикла основной сборки мусора. Следующие функции предназначены для создания и удаления предупреждений.
val create_alarm : (unit -> unit) -> alarm
create_alarm f организует вызов f в конце циклов основной сборки мусора, не вызванных f самим, начиная с текущего цикла или следующего. f будет выполняться в той же области, что и создала предупреждение, до тех пор, пока область не выйдет или delete_alarm не будет вызвано. Возвращается значение типа alarm, которое вы можете использовать для вызова delete_alarm.
Не гарантируется, что предупреждение Gc выполняется в конце каждого цикла основной сборки мусора, но гарантируется, что оно будет выполнено в конечном итоге.
В качестве примера, вот грубый способ прервать функцию, если потребление памяти программы превысит заданный 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 — это профилирующий движок, который случайным образом отбирает выделенные слова памяти.
© 1995-2024 INRIA.
https://ocaml.org/manual/5.2/api/Gc.html