Чрезвычайное использование памяти для индивидуального динамического распределения - PullRequest
0 голосов
/ 19 июля 2010

вот простой тест, который я провел на MSVC ++ 2010 под Windows 7:

// A struct with sizeof(s) == 4, e.g 4 bytes
struct s
{
    int x;
};

// Allocate 1 million structs
s* test1 = new s[1000000];

// Memory usage show that the increase in memory is roughly 4 bytes * 1000000 - As expected
// NOW! If I run this:
for (int i = 0; i < 1000000; i++)
    new s();

// The memory usage is disproportionately large. When divided by 1000000, indicates 64 bytes per s!!!

Это общеизвестно или я что-то упустил?Раньше я всегда использовал для создания объектов на лету, когда это необходимо.Например, new Triangle () для каждого треугольника в сетке и т. Д.

Действительно ли существует порядок издержек для динамического выделения памяти для отдельных экземпляров?:

Только что скомпилировал и запустил ту же программу на работе в Windows XP, используя g ++: Теперь издержки составляют 16 байтов, а не 64, как наблюдалось ранее!Очень интересно.

Ответы [ 4 ]

3 голосов
/ 19 июля 2010

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

В конце концов, есть издержки, связанные с отслеживанием распределения памяти, и резервирование очень небольших объемов не стоит.

1 голос
/ 19 июля 2010

Вы должны проверить реализацию malloc.Возможно, это прояснит ситуацию.

Не уверен, хотя можно ли где-нибудь просмотреть MSVC ++ malloc.Если нет, посмотрите на какую-то другую реализацию, возможно, они в некоторой степени похожи.

Не ожидайте, что реализация malloc будет легкой.Нужно искать свободное место на выделенных виртуальных страницах или выделять новую виртуальную страницу.И это должно сделать это быстро.Быстро настолько, насколько это возможно.И это должно быть многопоточным безопасным.Может быть, ваша реализация malloc имеет своего рода битовый вектор, в котором сохраняется, какие 64-битные чанки свободны на какой-то странице, и просто занимает следующий бесплатный чанк.

1 голос
/ 19 июля 2010

Обычно при любом выделении памяти накладные расходы. Теперь это из моих знаний о malloc, а не new, но я подозреваю, что это то же самое.

Часть области памяти, выделенная для (скажем) 30 байтов, обычно будет иметь заголовок (например, 16 байтов, и все подобные цифры приведены только в качестве примеров ниже, они могут отличаться) и может быть дополнен до 16 байтов для более легкого управления ареной.

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

Содержит информацию о размере блока как минимум и может также иметь защитные устройства памяти (для обнаружения повреждения арены).

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

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

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

1 голос
/ 19 июля 2010

Это для отладочной сборки? Потому что в отладочной сборке msvc будет размещать «охранники» вокруг объектов, чтобы посмотреть, не перезаписаны ли вы за границы объекта.

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