Spec-Zone.ru › Nim

doc/refc

Настройка сборщика мусора refc

Сборщик циклов

Сборщик циклов можно включить/отключить независимо от других частей сборщика мусора с помощью GC_enableMarkAndSweep и GC_disableMarkAndSweep.

Поддержка мягкого реального времени

Для включения поддержки реального времени необходимо определить символ useRealtimeGC с помощью --define:useRealtimeGC (можно добавить его в файл конфигурации). С этим переключателем сборщик мусора поддерживает следующие операции:

proc GC_setMaxPause*(maxPauseInUs: int)
proc GC_step*(us: int, strongAdvice = false, stackSize = -1)

Единицей измерения параметров maxPauseInUs и us являются микросекунды.

Эти две процедуры — два режима работы сборщика мусора реального времени:

  1. Режим GC_SetMaxPause

    Вы можете вызвать GC_SetMaxPause при запуске программы, и затем каждый запущенный цикл сборки мусора будет пытаться завершиться не более чем за maxPause времени. Однако возможно (и обычно так происходит), что работа не будет распределена равномерно, так как каждый вызов new может инициировать цикл сборки мусора и таким образом занять maxPause времени.

  2. Режим GC_step

    Это позволяет сборщику мусора выполнить некоторую работу в течение не более us времени. Это полезно вызывать в основном цикле, чтобы гарантировать, что сборщик мусора может выполнить свою работу. Чтобы привязать всю активность сборщика мусора к вызову GC_step, отключите сборщик мусора с помощью GC_disable при запуске программы. Если strongAdvice установлено в true, сборщик мусора будет вынужден выполнить цикл сбора. В противном случае сборщик мусора может решить ничего не делать, если не нужно собирать много мусора. Вы также можете указать текущий размер стека через параметр stackSize. Это может улучшить производительность, если вам известно, что нет уникальных ссылок Nim ниже определённой точки в стеке. Убедитесь, что указанный размер больше потенциального наихудшего случая.

    Это может улучшить производительность, если вам известно, что нет уникальных ссылок Nim ниже определённой точки в стеке. Убедитесь, что указанный размер больше потенциального наихудшего случая.

Эти процедуры обеспечивают "лучшее возможное" гарантированное реальное время; в частности, сборщик циклов не учитывает сроки выполнения. Отключите его, чтобы получить более предсказуемое поведение в реальном времени. Тесты показывают, что время максимальной паузы в 1 мс будет соблюдаться почти во всех случаях на современных процессорах (при отключенном сборщике циклов).

Измерение времени с помощью сборщиков мусора

Сборщики мусора используют способ измерения времени (см. lib/system/timers.nim для реализации):

  1. QueryPerformanceCounter и QueryPerformanceFrequency в Windows.
  2. mach_absolute_time в Mac OS X.
  3. gettimeofday в системах Posix.

Таким образом, он поддерживает внутреннее разрешение в наносекундах; однако API использует микросекунды для удобства.

Определите символ reportMissedDeadlines, чтобы сборщик мусора выводил сообщения всякий раз, когда пропущена временная метка. В будущих версиях сборщика отчетность будет расширена и поддерживаться API.

Настройка сборщика мусора

Сборщик проверяет, осталось ли время для работы после каждой workPackage-й итерации. В настоящее время это значение установлено в 100, что означает, что до 100 объектов просматриваются и освобождаются, прежде чем производится повторная проверка. Таким образом, workPackage влияет на точность измерения времени и может потребовать настройки в специализированных средах или на более старом оборудовании.

Координация потоков

При вызове функции NimMain() Nim инициализирует сборщик мусора для текущего потока, который, как правило, является основным потоком вашего приложения. Если ваш код C позже запускает другой поток и вызывает код Nim, сборщик мусора не будет работать должным образом, и произойдёт сбой.

Пока вы не используете эмуляцию переменных потока, Nim использует встроенные переменные потоков, новые версии которых вы получаете каждый раз при создании потока. Затем вы можете прикрепить сборщик мусора к этому потоку с помощью

system.setupForeignThreadGc()

Небезопасно отключать и включать сборщик мусора после вызова из фонового потока, даже если вызываемый код имеет короткое время существования.

Перед завершением потока необходимо разрушить сборщик мусора потока, чтобы предотвратить утечки памяти, вызвав

system.tearDownForeignThreadGc()

Отслеживание памяти

Если вам нужно передавать память, выделенную Nim, в C, вы можете использовать процедуры GC_ref и GC_unref для обозначения объектов как ссылочных, чтобы предотвратить их освобождение сборщиком мусора. Другие полезные процедуры из system, которые вы можете использовать для отслеживания памяти:

  • getTotalMem() Возвращает количество всей управляемой сборщиком мусора памяти.
  • getOccupiedMem() Байты, зарезервированные сборщиком мусора и используемые объектами.
  • getFreeMem() Байты, зарезервированные сборщиком мусора и не используемые.
  • GC_getStatistics() Статистика сборщика мусора в виде удобочитаемой строки.

Эти числа обычно относятся только к работающему потоку, а не ко всей куче, за исключением --mm:boehm и --mm:go.

В дополнение к GC_ref и GC_unref вы можете избежать сборщика мусора, вручную выделяя память с помощью процедур, таких как alloc, alloc0, allocShared, allocShared0 или allocCStringArray. Сборщик мусора не будет пытаться их освободить; вам нужно вызвать соответствующие пары dealloc (dealloc, deallocShared, deallocCStringArray и т. д.) после завершения работы с ними, иначе произойдёт утечка памяти.

Сброс кучи

Функция сброса кучи всё ещё находится на ранней стадии разработки, но она уже оказалась полезной для нас, поэтому она может быть полезной и для вас. Чтобы получить дамп кучи, скомпилируйте с -d:nimTypeNames и вызовите dumpNumberOfInstances в стратегической точке вашей программы. Это выведет список используемых типов в вашей программе, и для каждого типа общее количество экземпляров объектов этого типа, а также общее количество байтов, занимаемых этими экземплярами.

Числа учитывают количество объектов во всех кучах сборщика мусора, они относятся ко всем запущенным потокам, а не только к текущему. (Текущий поток — это поток, который вызывает dumpNumberOfInstances.) Это может измениться в будущих версиях.

© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/refc.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API