Как я могу узнать, сколько памяти занимает экземпляр класса C ++? - PullRequest
0 голосов
/ 19 марта 2010

Я занимаюсь разработкой класса Graph на основе библиотеки boost-graph.
Объект Graph содержит boost-graph, так сказать, adjacency_list и карту.При мониторинге общего использования памяти моей программой она потребляет довольно много (проверено с помощью pmap).
Теперь я хотел бы знать, сколько памяти в точности потребляется заполненным объектомэтого графа-класса?С заполненным я имею в виду, когда adjacency_list заполнен вершинами и ребрами.
Я обнаружил, что использование sizeof () не слишком далеко.Использование valgrind также является альтернативой , а не , так как ранее было сделано некоторое выделение памяти, и это делает использование valgrind нецелесообразным для этой цели.Меня также не интересует стоимость других частей программы в памяти, я хочу сосредоточиться на одном объекте.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 19 марта 2010

Если вы можете контролировать создание и заполнение объекта так, что в течение этого времени не выполняются никакие другие выделения, то один из способов сделать это - переопределить операторы new и delete своими собственными версиями, которые просто Подсчитайте общий размер выделения и сохраните его в глобальной переменной. Захватите общий размер в начале и конце, и разница должна быть разумным приближением к используемому размеру (не считая кучи служебных данных).

1 голос
/ 19 марта 2010

Я никогда не использовал adjacency_list, поэтому это просто идея , которая работает с контейнерами STL.

То есть с использованием adjacency_list говорит BGL uses containers from the STL such as std::vector, std::list, and std::set to represent the set of vertices and the adjacency structure. Хорошо, тогда вам просто нужно дать соседнему списку std :: vector, std :: list и std :: set, которые имеют свой собственный тип распределителя. Добавление собственного распределителя в контейнеры STL - простая задача . Сделав все это, вы просто должны получить от своих распределителей размер памяти, который был выделен при заполнении adjacency_list.

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

Обновление 1 На самом деле вы не сказали, почему вам нужно знать, сколько байтов потребляет ваш график. Если вам просто нужно получить этот номер только один раз, вам, вероятно, придется написать свою программу с и без заполнения графика. Затем запустите, например, UNIX95= ps -u $USER -o vsz,args и выясните разницу. Примерно вы получите размер вашего графика.

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

  1. Читайте о распределителях: C ++ Standard Allocator, Введение и реализация Распределители (STL)
  2. Попробуйте реализовать std :: vector с вашим собственным распределителем в качестве упражнения
  3. Попробуйте добавить счетчики байтов к вашему распределителю
  4. Попробуйте построить граф Boost с помощью распределителя. Настройка хранилища списков смежности
  5. Сделайте что-нибудь для подсчета байтов в элементах std :: string ваших контейнеров. По умолчанию они не будут использовать распределитель своего контейнера. Поэтому либо вместо этого используйте строки фиксированного размера, либо управляйте каким-либо образом, вставьте распределитель контейнера в члены этой строки. Опять же, взгляните на Добавление собственного распределителя в контейнеры STL

Кстати, если вы не хотите заново изобретать распределитель C ++, вы можете просто использовать что-то вроде этого:

template <typename T> class your_allocator {    
public:
// here you need to put everything that is required by C++ standard
// and calls finally send to std_allocator_    
private:
    std::allocator<T> std_allocator_;    
};
0 голосов
/ 20 марта 2010

Теперь мне удалось все сжать, так что я могу подумать о профилировании с помощью valgrind.
Затем я использовал "--tool = massif", чтобы проверить потребление памяти кучи. Я использовал следующий код для создания экземпляра моего класса Graph

    typedef Graph<VertexProperties, EdgeProperties> MyGraph;
    MyGraph* G;
    G = new MyGraph(*vertex_props);

Конструктор построен таким образом, что он получает список пар VertexProperties, которые равны ребрам, а затем сохраняет все с помощью adjacency_list.
Профиль массива затем дал мне следующие результаты. Для простоты я разместил их в пастбине: http://dpaste.com/hold/174033/
Вы можете видеть там диаграмму для полного выполнения, и пик достигнут на снимке 83 с 235,4 МБ.
Мой вопрос сейчас, это общий максимальный объем памяти в куче, используемой моей программой? Как насчет ок. 1 ГБ памяти, которую мне возвращает pmap для моей программы? Как эти ценности объединяются?
И самое главное, если посмотреть на детали для снимка 83, это говорит:

  1. 32,76% (80 842 846B) для std :: string :: _ Rep :: _ S_create (....)
  2. 15,94% (39 341 760 В) для std :: _ Rb_tree>
  3. 11,91% (29 389 824 В) для основного (new_allocator.h: 92)

Я правильно понимаю, что 1. говорит мне, что ок. 80 МБ расходуется на std :: string и 2. говорит мне, что мой график занимает ок. 40MB
Что 3. тогда скажи мне?

Спасибо.

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