Что происходит с кучей Vista? - PullRequest
1 голос
/ 17 декабря 2010

Я пытаюсь лучше понять, почему куча Windows Vista ведет себя так, как она работает. Рассмотрим следующую очень простую программу:

#include <vector>
#define NUM_ALLOCS 10000000

int _tmain(int argc, _TCHAR* argv[])
{
    for (int iteration=0; iteration<10000; ++iteration) {
        std::vector<unsigned char *> buffer;
        buffer.reserve(NUM_ALLOCS);
        for (int i=0;i<NUM_ALLOCS;++i) {
            buffer.push_back(new unsigned char);
        }
        for (int i=0;i<NUM_ALLOCS;++i) {
            delete buffer[i];
        }
    }

    return 0;
}

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

Поведение, которое я наблюдаю в 64-разрядной версии Windows Vista, заключается в том, что пиковое использование памяти (согласно отчету диспетчера задач или vmmap ) остается примерно постоянным с течением времени, тогда как наименьшее использование памяти, о котором сообщалось, растет пока он не приблизится к пиковому использованию памяти.

В 64-разрядной версии Windows 7 минимальное зарегистрированное использование памяти не увеличивается со временем.

Редактировать: Я тестировал на двух 64-разрядных компьютерах с Windows Vista с 8 ГБ / 4 ГБ оперативной памяти и на одном 64-разрядном компьютере с Windows 7 с 4 ГБ оперативной памяти. Я проверил машину на 8 ГБ со сценариями с низким и высоким использованием памяти.

Редактировать: я построил приведенный выше пример с Visual Studio 2005 и 2010 с тем же результатом.

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

Кто-нибудь имеет представление о механизмах кучи? Нужно ли делать что-то еще, чтобы убедить менеджер кучи полностью освободить использованную память кучи? Есть ли альтернативные стратегии, которые я должен использовать, например, создать отдельную кучу и затем уничтожить ее?

Любые комментарии или идеи приветствуются!

Ответы [ 4 ]

1 голос
/ 17 декабря 2010

Может ли это быть Куча с низкой фрагментацией ?

Мне кажется, что я где-то читал, что LFH по умолчанию включен в Windows 7. Однако быстрый поиск не выявил подтверждения, поэтому я могу ошибаться.

Есть простой способ проверить, хотя. Вызовите HeapQueryInformation для дескриптора, полученного из GetProcessHeap , и сравните результаты в разных системах.

0 голосов
/ 27 января 2011

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

Даже без этой оптимизации средство кучи может свободно удерживать в куче кучи, из которой было сделано выделение. Для возврата памяти в систему (VirtualFree) все блоки в блоке размером 64 КБ должны быть освобождены и объединены менеджером кучи.

0 голосов
/ 27 января 2011

atzz на правильном пути, но такое поведение будет происходить с любой кучей - когда вы вызываете эту первую «новую» с однобайтовым размером, куча выделяет «корзину» и предварительно выделяет определенный блок памяти (вероятно, несколько кратно размеру страницы, 4K); таким образом, когда поступают последующие выделения того же размера, это может очень быстро дать вам память.

Кроме того, когда вы вызываете delete, он просто помечает этот регион как нераспределенный, но сохраняет его на тот случай, если позже вам понадобится новый объект аналогичного размера.

Если диспетчер кучи работает так, как вы описали, он будет работать очень медленно, потому что ему придется постоянно спрашивать ядро: «Можете ли вы дать мне еще один байт?» и "Преобразуйте это, пожалуйста!" (на самом деле это невозможно, так как минимальное выделение, которое вы можете попросить у ядра, - это размер страницы, насколько я помню)

0 голосов
/ 17 декабря 2010

Вы пробовали это под давлением памяти?Нет смысла освобождать память, если это не нужно кому-то еще.

...