Удаление объекта со списком указателей на самом деле не освобождает соответствующую память - PullRequest
0 голосов
/ 04 марта 2012

У меня есть класс со списком указателей на объекты того же класса в качестве атрибута (Children).У меня проблема в том, что когда я создаю объект этого класса, добавляю к нему потомки и затем пытаюсь удалить его, он не освобождает память (судя по системному монитору).Я использую Ubuntu с g ++.

Следующий код хорошо иллюстрирует мою проблему.Он создает объект, добавляет к нему десять миллионов детей и затем удаляет его.Использование памяти увеличивается с 1,1 до 1,7 ГБ при выполнении программы и застревает там даже после удаления объекта.

anyone Кто-нибудь имеет представление о том, что происходит?много.

class UDVertex
{
  public:
   int ID;
   list<UDVertex *> Children;
};

void GetChildren(UDVertex * rootVT);

int main()
{
    UDVertex * MyVertex;

    MyVertex = new UDVertex;
    MyVertex -> ID = 0;

    GetChildren(MyVertex);

    while( ! MyVertex -> Children . empty() )
    {
         delete MyVertex -> Children . front();

         MyVertex -> Children . pop_front();
    }

    delete MyVertex;

    std::cout << "Press enter to continue...";
    std::cin.get(); 

    return 0;
}

void GetChildren(UDVertex * rootVT)
{
    UDVertex * Child;
    int i;

    for (i = 0; i < 10000000; i++)
    {
        Child = new UDVertex;
        Child -> ID = i + 1;

        rootVT -> Children . push_back ( Child ) ;

    }   

}

Ответы [ 3 ]

1 голос
/ 04 марта 2012

Это совершенно нормально. Виртуальная память не считается дефицитным ресурсом, поэтому нет необходимости восстанавливать ее. Физическая память восстанавливается только тогда, когда она нужна для каких-то других целей, поэтому нет необходимости немедленно ее восстанавливать. Вам нужно использовать более сложные инструменты, чтобы узнать, была ли виртуальная память помечена как свободная (чтобы ее можно было повторно использовать) внутри процесса. Это то, что вас должно волновать (если вы не беспокоитесь о чем-то необычном, например о фрагментации).

1 голос
/ 04 марта 2012

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

0 голосов
/ 04 марта 2012

Проблема заключается в вашем методе измерения памяти.
«Системный монитор» контролирует память, выделенную для процессов (что делается огромными порциями).

Внутри процессов память выделяется / восстанавливается (после нового / удаления) библиотекой времени выполнения;какие дорожки создаются и удаляются из объектов (которые обычно крошечные по сравнению со страницами, выделенными для процессов).«Системный монитор» не дает вам знать, сколько памяти в данный момент активно используется приложением (вашей частью приложения) и сколько времени удерживает среда выполнения.

Простой тест будетпопытаться снова выделить объекты (выделить всю память (контрольный размер), освободить всю память (контрольный размер), выделить всю память (контрольный размер)).

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

...