Spec-Zone.ru › Kotlin 1.8

Управление памятью в Kotlin/Native

На этой странице описаны возможности нового менеджера памяти, включенного по умолчанию начиная с Kotlin 1.7.20. Обратитесь к нашему руководству по миграции, чтобы перенести свои проекты с устаревшего менеджера памяти.

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

При включении этого параметра GC не собирает Kotlin объекты, поэтому потребление памяти будет увеличиваться до тех пор, пока программа работает. Будьте осторожны, чтобы не исчерпать системную память.

Потребление памяти

Если в программе нет утечек памяти, но вы всё ещё видите неожиданно высокое потребление памяти, попробуйте обновить 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 по какой-либо причине не работает для вас, попробуйте следующий обходной путь для реализации запуска тестов:

package testlauncher import platform.CoreFoundation.* import kotlin.native.concurrent.* import kotlin.native.internal.test.* import kotlin.system.* fun mainBackground(args: Array<String>) { val worker = Worker.start(name = "main-background") worker.execute(TransferMode.SAFE, { args.freeze() }) { val result = testLauncherEntryPoint(it) exitProcess(result) } CFRunLoopRun() error("CFRunLoopRun should never return") }

Затем, скомпилируйте двоичный файл тестов с флагом компилятора -e testlauncher.mainBackground.

Устаревший менеджер памяти

Если необходимо, вы можете переключиться на устаревший менеджер памяти. Установите соответствующий параметр в вашем gradle.properties:

kotlin.native.binary.memoryModel=strict
  • Поддержка кэша компилятора недоступна для устаревшего менеджера памяти, поэтому время компиляции может ухудшиться.

  • Этот параметр Gradle для возвращения к устаревшему менеджеру памяти будет удалён в будущих версиях.

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

Что дальше

  • Миграция с устаревшего менеджера памяти

  • Настройка интеграции с iOS

Последнее изменение: 10 января 2023
Kotlin/Native как динамическая библиотека – учебник Интеграция с iOS

© 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

Spec-Zone.ru

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