Мне надо приближённо оценить объём памяти, который занимает конкретный std:: контейнер.
Чтобы логировать распределение памяти, потом анализировать логи.
Как это правильно сделать?
Для простого типа TData (не содержащего в себе контейнеры и пр. динамически выделяемую память), я использую:
Здравствуйте, Баян 75, Вы писали:
Б7>Мне надо приближённо оценить объём памяти, который занимает конкретный std:: контейнер. Б7>Чтобы логировать распределение памяти, потом анализировать логи. Б7>Как это правильно сделать?
Б7>Может, уже есть какие-то функции?
Есть. Аллокатор, который ты передаешь в вектор и прочая, предоставляет функции allocate/deallocate — наиболее естественное место, чтобы вести статистику. Если хочешь профилировать вообще всё — можешь просто захачить std::allocator (может статься, что он уже не умеет логировать в твоей поставке STL под дебагом — проверь). Если не все, а что-то конкретное — передавай аллокатор в это конкретное.
Здравствуйте, jazzer, Вы писали:
J>Есть. Аллокатор, который ты передаешь в вектор и прочая, предоставляет функции allocate/deallocate — наиболее естественное место, чтобы вести статистику. Если хочешь профилировать вообще всё — можешь просто захачить std::allocator (может статься, что он уже не умеет логировать в твоей поставке STL под дебагом — проверь). Если не все, а что-то конкретное — передавай аллокатор в это конкретное.
Спасибо!
Кажется, это — то что нужно. Буду смотреть.
Здравствуйте, Баян 75, Вы писали:
Б7>Здравствуйте, smeeld, Вы писали:
S>> size_t sz=sizeof(Mp::value_type)*mp.size();
Б7>Это, кажется, слишком приближённо. Б7>Но, всё равно, спасибо.
Здравствуйте, Баян 75, Вы писали:
Б7>Здравствуйте, smeeld, Вы писали:
S>> size_t sz=sizeof(Mp::value_type)*mp.size();
Б7>Это, кажется, слишком приближённо.
Это мягко говоря
sizeof(Mp::value_type) — это не размер узла, а лишь размер того, что внутри узла лежит. А сам узел наружу не выставлен, это деталь реализации (а это, в частности, значит, что реализована работа с узлами может быть как угодно, единственное, что гарантируется — что в конечном итога она как-то пойдет через аллокатор).
Б7>Это, кажется, слишком приближённо. Б7>Но, всё равно, спасибо.
value_type-это тот объект(его typedef) который и есть сохраняемый в контейнере
объект, под который память и выделяется. Например для map из GNU-сных запилов;
Здравствуйте, smeeld, Вы писали:
S>value_type-это тот объект(его typedef) который и есть сохраняемый в контейнере S>объект, под который память и выделяется. Например для map из GNU-сных запилов;
Нет, там ещё структура под узел, в которой и лежит value_type: к примеру, https://github.com/llvm-mirror/libcxx/blob/master/include/__tree#L595
Здравствуйте, smeeld, Вы писали:
S>Здравствуйте, flаt, Вы писали:
F>>Нет, там ещё структура под узел, в которой и лежит value_type:
S>Это про _Rb_tree_node<_Val> ?
S>Ну, мне думалось, что она в параллельном пространстве аллокатится.
Даже если так — ее не надо учитывать, выясняя расходы памяти?
Здравствуйте, smeeld, Вы писали:
J>>Даже если так — ее не надо учитывать, выясняя расходы памяти? S>А как с вопросом статистики памяти, не заменяя std::allocator?
Сделать свои ::operator new и т.п., измерить статистику памяти в ограниченном scope, причём при наличии других потоков — отфильтровать по tid/tls.
Здравствуйте, jazzer, Вы писали:
J>а это, в частности, значит, что реализована работа с узлами может быть как угодно, единственное, что гарантируется — что в конечном итога она как-то пойдет через аллокатор
<зануда_mode /> Думаю что жёсткой гарантии нет: например эффекты стандартных контейнеров undefined для incomplete типов, и соответственно они могут сделать small size optimization в обход аллокатора.
Но на практике это ничего не меняет — я не встречал std::map с подобной оптимизацией.
Здравствуйте, smeeld, Вы писали:
S>Здравствуйте, jazzer, Вы писали:
J>>Даже если так — ее не надо учитывать, выясняя расходы памяти?
S>А как с вопросом статистики памяти, не заменяя std::allocator?
А что с ним? и в чем проблема заменить аллокатор или просто его захачить для твоих нужд? Благо STL вся в исходниках доступна Сделай спец.дефайн и под соответствующим ифдефом вставь запись статистики