Измерьте максимальное использование памяти во время вызова функции - PullRequest
0 голосов
/ 21 января 2019

У меня есть библиотека Linux / Mac C ++, которая выполняет серию шагов в форме вызовов функций. Я хотел бы измерить максимальное использование памяти на каждом этапе.

Я не заинтересован в специальных решениях, таких как запуск другого потока, который опрашивает использование памяти, запуск профилировщика и т. Д.

До сих пор я обнаружил, что getrusage() присутствует в Mac и Linux и возвращает максимальное использование памяти, однако, похоже, нет способа сбросить этот максимум после каждого вызова функции.

Есть ли способ обойти это ограничение?

Редактировать: Чтобы было ясно, я не хочу командовать malloc() / free() и регистрировать все. Мне нужно решение, которое подходит для запуска производственного кода.

Ответы [ 2 ]

0 голосов
/ 21 января 2019

Вызовы 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, если кто-то не может исправить меня.

0 голосов
/ 21 января 2019

Я просмотрел исходный код Linux и нашел this :

        /*
         * 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.

...