Как освободить выделенную память в рекурсивной функции в C ++

0

У меня есть рекурсивный метод в классе, который вычисляет несколько этапов (неважно, что это такое). Если он заметит, что вероятность успеха на сцене будет низкой, этап будет отложен, сохранив его в очереди, и программа будет искать более поздний этап позже. Он захватывает сцену, копирует данные для работы и удаляет сцену.

Программа работает нормально, но у меня проблема с памятью. Поскольку эта программа рандомизирована, может случиться так, что она задерживает до 10 миллионов этапов, что приводит к чему-то вроде использования памяти от 8 до 12 ГБ (или больше, но оно падает до того, как это произойдет). Похоже, что программа никогда не освобождает память для удаленной ступени, пока не дойдет до конца стека вызовов рекурсивной функции.

class StageWorker
{
private:
    queue<Stage*> delayedStages;

    void perform(Stage** start)
    {
       // [long value_from_stage = (**start).value; ]

       delete *start;

       // Do something here

       // Delay a stage if necessary like this
       this->delayedStages.push(new Stage(value));

       // Do something more here

       // Look for delayed stages like this
       Stage* front = this->delayedStages.front();
       this->delayedStages.pop();
       this->perform(&front);
    }
}

Я использую указатель на указатель, поскольку я думал, что память не освобождена, потому что есть указатель (фронт *), который указывает на сцену. Поэтому я использовал указатель, указывающий на указатель, и поэтому могу его удалить. Но, похоже, это не сработает. Если я смотрю использование памяти на мониторе производительности (в Windows), он выглядит примерно так: Изображение 174551
Я отметил конец рекурсивных вызовов. Это также примерный сюжет. реальные данные, но в очень маленьком сценарии.

Любые идеи о том, как освободить память от более не используемых мудрецов до достижения стека вызовов?

редактировать
Я последовал советам и удалил указатели. Итак, теперь это выглядит так:

class StageWorker
{
private:
    queue<Stage> delayedStages;

    void perform(Stage& start)
    {
       // [long value_from_stage = start.value; ]

       // Do something here

       // Delay a stage if necessary like this
       this->delayedStages.push(Stage(value));

       // Do something more here

       // Look for delayed stages like this          
       this->perform(this->delayedStages.front());
       this->delayedStages.pop();
    }
}

Но это ничего не меняло, использование памяти было таким же, как и раньше.

Как уже упоминалось, это проблема мониторинга. Есть ли лучший способ проверить точное использование памяти?

  • 0
    Просто вопрос: почему std::queue<Stage*> а не std::queue<Stage> ? Т.е. почему вы не хотите, чтобы стандартная библиотека позаботилась об управлении памятью за вас? Если с ++ 11 не проблема, вы можете даже использовать emplace если вы заинтересованы в копировании Stages.
  • 0
    Также, So I used a pointer that point to the pointer, and so I can delete it. : ссылка на указатель была бы намного понятнее.
Показать ещё 14 комментариев
Теги:
recursion
memory-management

1 ответ

0
Лучший ответ

Просто, чтобы ответить на этот вопрос:

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

На самом деле это была проблема. Код, который я предоставил в редактировании (после замены указателей ссылками), освобождает пространство правильно, но он не возвращается ОС (в данном случае Windows). Так что с монитора видно, что пространство не освобождено.

Но затем я сделал несколько экспериментов и увидел, что освобожденная память повторно используется приложением, поэтому нет необходимости запрашивать ОС для большей памяти.

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

  • 0
    Итак, вы видите максимальный объем памяти, который ваша программа использует в какой-то момент в течение своего жизненного цикла, и он слишком велик для большого количества этапов. Это означает, что миллионы объектов, находящихся в очереди в некоторой (максимальной) точке, занимают слишком много памяти. Немного, что вы можете с этим поделать, если столкнетесь с таким количеством этапов и этим алгоритмом. Но, возможно, вы можете сохранить в очереди не завершенные объекты сцены, а лишь небольшую информацию, достаточную для их воссоздания?
  • 0
    да, я должен каким-то образом ограничить максимум этапов. Я уже сократил стадию до минимальной информации, необходимой для восстановления полной информации о сцене. Теперь я подумаю о способе ограничения количества хранимых этапов без нарушения алгоритма. Но вопрос был только в том, смогу ли я улучшить использование памяти, освободив ее. Теперь я знаю, это уже работает.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню