0Pricing
C++ Academy · Урок

Выделение памяти для кадра сопрограммы

Разбирайтесь в выделении памяти для кадра сопрограммы и его времени жизни.

«Выделение памяти для кадра сопрограммы» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Где хранится состояние

Локальные переменные в корутине сохраняются между приостановками. Они не могут находиться в стеке — между приостановками функция возвращает управление. Поэтому они находятся во фрейме корутины, выделенном в куче.

Что содержит фрейм

Фрейм содержит:

  • Параметры корутины
  • Объект обещания
  • Локальные переменные, сохраняющиеся между приостановками
  • Указатели на функции возобновления и уничтожения

Стоимость выделения памяти в куче

Каждый вызов корутины выделяет фрейм. Выделение памяти не бывает бесплатным — это существенно для корутин с высокой частотой вызова. Оптимизирующие компиляторы могут устранить выделение памяти, если время жизни ограничено, — это называется HALO (оптимизация устранения выделения памяти в куче, eLision).

Когда срабатывает HALO

Компилятор может избежать выделения памяти в куче, если:

  • Время жизни корутины доказуемо ограничено
  • Встраивание позволяет доказать, что фрейм помещается в стеке
  • Размер фрейма фиксирован во время компиляции

Пользовательские распределители памяти

Вы можете предоставить пользовательские распределители памяти для фреймов корутин, перегрузив operator new внутри типа promise_type.

struct promise_type {
    void* operator new(size_t size) {
        return std::malloc(size);
    }
    void operator delete(void* ptr) {
        std::free(ptr);
    }
};

Пулы фреймов

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

Размер фрейма

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

Уменьшение размера фрейма

Советы:

  • Жёстко ограничивайте область видимости переменных
  • Избегайте больших локальных массивов — явно используйте кучу
  • Переносите временные объекты в отдельные вспомогательные функции, не являющиеся корутинами

Анализ фреймов

Компиляторы могут выводить размеры фреймов. В clang используйте -fcoro-aligned-allocation и выполняйте проверку с помощью диагностических параметров. Дизассемблирование показывает размещение элементов во фрейме.

Время жизни и очистка

Фрейм корутины уничтожается после завершения final_suspend (или раньше, если его уничтожить явно). Члены RAII корректно уничтожаются.

Безопасность памяти

Дескриптор корутины — это обычный указатель. Хранение дескриптора после уничтожения корутины приводит к неопределённому поведению. Типы библиотек оборачивают дескрипторы в RAII, чтобы предотвратить это.

Когда стоит беспокоиться

В большинстве приложений не нужно задумываться о выделении фреймов. Беспокоиться стоит только при наличии миллионов корутин или крайне жёстких требований к производительности. Сначала выполните профилирование.

Быстрая проверка

Почему фрейм корутины обычно находится в куче?

Итоги

Корутины выделяют фрейм в куче, чтобы сохранять состояние между приостановками. Компиляторы могут устранять это выделение (HALO), когда это возможно. Пользовательские распределители памяти и пулы фреймов помогают в системах с высокой пропускной способностью, но большинству кода об этом беспокоиться не нужно.

Часто задаваемые вопросы

Урок «Выделение памяти для кадра сопрограммы» бесплатный?

Да — полный текст урока «Выделение памяти для кадра сопрограммы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Выделение памяти для кадра сопрограммы»?

Разбирайтесь в выделении памяти для кадра сопрограммы и его времени жизни. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Выделение памяти для кадра сопрограммы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Концепции сопрограмм: co_await, co_yield, co_return
  2. Реализация простого генератора
  3. Асинхронные задачи и типы awaiter
  4. Выделение памяти для кадра сопрограммы
← Назад к C++ Academy