Память подсчета объектов неточна? - PullRequest
0 голосов
/ 13 февраля 2012

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

Каждый раз, когда создается объект CacheEntry, он добавляет размер объекта CacheEntry (по-видимому, 64 байта) плюс количество байтов, используемых во внутренних массивах для счетчика, сколько байтов используется.Когда объект CacheEntry удаляется, он вычитает эту сумму.Я могу подтвердить, что, по крайней мере, математика верна.

Однако при запуске внутри NetBeans профилировщик памяти сообщает значительно разных чисел.Примерно в два раза выше, если быть точным.Это не утечка памяти, и это определенно связано с количеством существующих объектов CacheEntry .Увеличение объема данных, хранящихся во внутренних массивах, фактически сближает числа (в отличие от дальнейшего разделения, если это было неправильно рассчитано);Исходя из этого, я пришел к выводу, что накладные расходы на наличие объекта CacheEntry в памяти почти вдвое превышают размер sizeof ().Он не растет поэтапно или «порциями».

Существует ли какая-то общая причина, по которой это может произойти?

ОБНОВЛЕНИЕ: Просто чтобы проверить, я выполнил свои тесты безпрофилировщик на месте.Linux сообщает об одном и том же VmHWM / VmRSS, так что профилировщик памяти определенно не влияет на вычисления.

Ответы [ 3 ]

0 голосов
/ 13 февраля 2012

Существует ли какая-то общая причина, по которой это может произойти?

Да, это может быть внутренняя фрагментация и накладные расходы менеджера памяти.Если ваш тип данных небольшой (например, sizeof(CacheEntry) равен 8 байтам), new такой тип данных может привести к увеличению объема памяти.Он частично используется для внутренней бухгалтерии malloc (обычно он где-то хранит размер блока), частично для заполнения, необходимого для выравнивания вашего типа данных по его естественной границе (например, 8 байтов данных + 4 байта бухгалтерии + 4 байта заполнения, необходимых для выравниваниявсе это на 8-байтовой границе).

Вы можете решить это, выделяя из одного непрерывного массива CacheEntry (например, CacheEntry array[1000] занимает ровно 1000*sizeof(CacheEntry) байт).Вы должны будете отслеживать использование отдельных элементов в массиве, но это должно быть выполнимо без дополнительной памяти.(например, запустив свободный список записей вместо бесплатных).

0 голосов
/ 21 февраля 2012

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

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

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

0 голосов
/ 13 февраля 2012

Возможно, профилировщик добавляет опорные объекты для отслеживания объектов?Видите ли вы те же результаты при запуске приложения в выпуске по сравнению с отладкой?

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