Измерьте максимальное использование памяти во время вызова функции
У меня есть библиотека Linux/Mac C++, которая выполняет серию шагов в виде вызовов функций. Я хотел бы измерить максимальное использование памяти на каждом этапе.
Меня не интересуют специальные решения, такие как запуск другого потока, который опрашивает использование памяти, запуск профилировщика и т. Д.
Пока я нашел getrusage()
присутствует в Mac и Linux и возвращает максимальное использование памяти, однако, кажется, нет способа сбросить этот максимум после каждого вызова функции.
Есть ли способ обойти это ограничение?
Редактировать: чтобы быть ясно, я не хочу командовать malloc()
/free()
и войти все. Я хочу решение, которое подходит для запуска производственного кода.
2 ответа
Я просмотрел исходный код Linux и нашел это:
/*
* Writing 5 to /proc/pid/clear_refs resets the peak
* resident set size to this mm's current rss value.
*/
Я еще не пробовал, но выглядит многообещающе.
Редактировать: он был добавлен в этот коммит
Редактировать 2: я посмотрел исходный код ядра MacOS - соответствующее значение хранится в resident_max
, К сожалению, кажется, что нет функции, чтобы сбросить его.
Редактировать 3: В Linux вы можете получить максимально выделенную память, используя malloc_info()
однако, кажется, нет способа сбросить его. Это также зависит от вас, используя glibc
,
malloc
а также free
звонки - это не просто тривиальные обертки sbrk
а также mmap
системные вызовы. Это делает getrusage
вернуть то, что не соответствует звонкам malloc
а также free
, Любая нетривиальная реализация этих функций будет управлять свободным списком внутри самого процесса, прежде чем думать о возврате чего-либо в систему.
Программа вызывает free
(или же delete
в этом отношении), и память не сразу возвращается операционной системе (возможно, никогда). free
память может быть повторно использована задачей, если она вызывает malloc
, но не другими процессами. Это делает getrusage
правильный с точки зрения ОС, но не правильный с точки зрения программы.
В Linux вы можете использовать mallinfo()
#include <malloc.h>
#include <cinttypes>
std::size_t memsize()
{
auto data = mallinfo();
return data.arena - data.fordblks + data.hblkhd;
}
Вот, memsize()
вернет количество байтов, выделенных с точки зрения программы. Он учитывает различные методы распределения, такие как sbrk
а также mmap
и рассматривает округление и издержки как часть выделенной памяти malloc()
(а также new
).
С OSX все не так ярко. Вы можете взглянуть на исходный код яблочной функции malloc() и, в частности, на mstats
, который гласит в комментарии:
/*
* A Glibc-like mstats() interface.
*
* Note that this interface really isn't very good, as it doesn't understand
* that we may have multiple allocators running at once. We just massage
* the result from malloc_zone_statistics in any case.
*/
Это выглядит не очень многообещающе и:
#include <malloc/malloc.h>
#include <cinttypes>
std::size_t memsize()
{
auto data = mstats();
return data.bytes_used;
}
По моим экспериментам выглядит не очень хорошо. Но это может быть лучше, чем ничего, или просто полагаться на getrusage
, Я думаю, что вам не повезло на OSX, если кто-то не может исправить меня.