Управление памятью в Kotlin/Native
Kotlin/Native использует современный менеджер памяти, аналогичный JVM, Go и другим распространённым технологиям:
Объекты хранятся в общей куче и доступны из любого потока.
Трассируемый сборщик мусора (GC) периодически выполняется, чтобы собрать объекты, недоступные из «корней», таких как локальные и глобальные переменные.
Менеджер памяти одинаков для всех целей Kotlin/Native, за исключением wasm32, который поддерживается только в устаревшем менеджере памяти.
Сборщик мусора
Точный алгоритм GC постоянно совершенствуется. По состоянию на 1.7.20 это сборщик мусора «Остановить-мир» (Stop-the-World) «Отметить и скопировать» (Mark and Concurrent Sweep), который не разделяет кучу на поколения.
GC выполняется в отдельном потоке и запускается на основе таймера и эвристик давления на память, или может быть вызван вручную.
Включение сборки мусора вручную
Для принудительного запуска сборщика мусора вызовите kotlin.native.internal.GC.collect(). Это запускает новую коллекцию и ожидает её завершения.
Отслеживание производительности GC
Пока нет специальных инструментов для отслеживания производительности GC. Однако, всё ещё можно просматривать журналы GC для диагностики. Для включения журналирования установите следующий флаг компиляции в скрипте Gradle:
-Xruntime-logs=gc=info
В настоящее время журналы выводятся только в stderr.
Отключение сборки мусора
Рекомендуется поддерживать включённый GC. Однако, вы можете отключить его в определённых случаях, например, для тестирования или если у вас кратковременная программа. Для этого установите следующий флаг компиляции в скрипте Gradle:
-Xgc=noop
Потребление памяти
Если в программе нет утечек памяти, но вы всё ещё видите неожиданно высокое потребление памяти, попробуйте обновить Kotlin до последней версии. Мы постоянно улучшаем менеджер памяти, поэтому даже простое обновление компилятора может улучшить потребление памяти.
Другой способ исправить высокое потребление памяти связан с mimalloc, по умолчанию используемым выделетелем памяти для многих целей. Он предварительно выделяет и сохраняет системную память для повышения скорости выделения.
Чтобы избежать этого, есть несколько вариантов, которые могут потребовать снижения производительности:
Переключите выделетель памяти с
mimallocна системный выделетель. Для этого установите опцию-Xallocator=stdв скрипте Gradle.-
Начиная с Kotlin 1.8.0-Beta, вы также можете указать
mimallocнезамедлительно возвращать память системе. Это незначительная потеря производительности, но даёт менее определённые результаты.Для этого включите следующий бинарный параметр в свой
gradle.propertiesфайл:kotlin.native.binary.mimallocUseCompaction=true
Если ни один из этих вариантов не улучшил потребление памяти, сообщите об ошибке в YouTrack.
Тестирование юнит-тестов в фоновом режиме
В юнит-тестах ничего не обрабатывает очередь главного потока, поэтому не используйте Dispatchers.Main если оно не было смоделировано, что можно сделать, вызвав Dispatchers.setMain из kotlinx-coroutines-test.
Если вы не полагаетесь на kotlinx.coroutines или Dispatchers.setMain по какой-либо причине не работает для вас, попробуйте следующий обходной путь для реализации запуска тестов:
Затем, скомпилируйте двоичный файл тестов с флагом компилятора -e testlauncher.mainBackground.
Устаревший менеджер памяти
Если необходимо, вы можете переключиться на устаревший менеджер памяти. Установите соответствующий параметр в вашем gradle.properties:
kotlin.native.binary.memoryModel=strict
Если у вас возникли проблемы с миграцией с устаревшего менеджера памяти или вы хотите временно поддерживать как текущий, так и устаревший менеджеры памяти, обратитесь к нашим рекомендациям в руководстве по миграции.
Что дальше
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/native-memory-manager.html