Как получить высшую отметку использования памяти на OSX

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

Взяв за простой пример

grep pattern file

Я хотел бы увидеть, как использование памяти зависит от размера pattern и размер file,

Для сложности времени, я бы сделал предположение, а затем запустить

time grep pattern file

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

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

я видел time -v предлагается, но на моем компьютере этот флаг недоступен (работает bash на OSX) и не знаю, где найти версию, которая его поддерживает.

Я также видел, что в Linux эта информация доступна через proc файловая система, но опять же, она не доступна для меня в моем контексте.

Мне интересно, если dtrace может быть подходящим инструментом, но опять же обеспокоен тем, что простая основанная на образце цифра не может быть истинным верхним знаком?

Кто-нибудь знает инструмент или подход, который подойдет для OSX?

редактировать

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

2 ответа

Решение

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

В частности, для небольших команд было бы легче отслеживать отдельные распределения, хотя даже там вы должны быть уверены, что включили все возможные источники. В дополнение к malloc() и т. д., процесс может расширить свою кучу с brk() или получить анонимную память, используя mmap(),

Вот сценарий DTrace, который отслеживает malloc(); Вы можете расширить его, чтобы включить другие функции распределения. Обратите внимание, что он не подходит для многопоточных программ, так как использует некоторые неатомарные переменные.

bash-3.2# cat hwm.d
/* find the maximum outstanding allocation provided by malloc() */
size_t total, high;

pid$target::malloc:entry
{
    self->size = arg0;
}

pid$target::malloc:return
/arg1/
{
    total += self->size;
    allocation[arg1] = self->size;
    high = (total > high) ? total : high;
}

pid$target::free:entry
/allocation[arg0]/
{
    total -= allocation[arg0];
    allocation[arg0] = 0;
}

END
{
    printf("High water mark was %d bytes.\n", high);
}
bash-3.2# dtrace -x evaltime=exec -qs hwm.d -c 'grep maximum hwm.d'
/* find the maximum outstanding allocation provided by malloc() */
High water mark was 62485 bytes.

bash-3.2#

Гораздо более всестороннее обсуждение распределителей памяти содержится в этой статье Брендана Грегга. Это дает гораздо лучший ответ, чем мой ответ на ваш вопрос. В частности, он включает ссылку на скрипт memleak.d; измените это, чтобы включить метки времени для распределения и освобождения, чтобы вы могли отсортировать его выходные данные по времени. Затем, возможно, используя сопровождающий скрипт в качестве примера, используйте perl отслеживать текущее непогашенное общее распределение и высшую отметку. Такая комбинация DTrace/ Perl была бы подходящей для отслеживания многопоточных процессов.

Ты можешь использовать /usr/bin/time -l (который не является time встроенный в macos) и прочитайте "максимальный размер резидентного набора", который не является точно верхним знаком, но может дать вам некоторое представление.

$ /usr/bin/time -l ls
...
        0.00 real         0.00 user         0.00 sys
    925696  maximum resident set size
         0  average shared memory size
         0  average unshared data size
         0  average unshared stack size
       239  page reclaims
         0  page faults
         0  swaps
         0  block input operations
         0  block output operations
         0  messages sent
         0  messages received
         0  signals received
         3  voluntary context switches
         1  involuntary context switches

Смысл этого поля объясняется здесь.

Пытался getrusage(). Неточные результаты. Пробовал инструменты. Боль в заднице.

Лучшее решение на сегодняшний день: valgrind + massif.

  • на основе командной строки: легко запускать, создавать сценарии и автоматизировать; нет приложений для открытия, меню для нажатия, бла-бла; может работать в фоновом режиме и т. д.
  • предоставляет наглядный график - в вашем терминале - использования памяти с течением времени
    valgrind --tool=massif /path/to/my_program arg1 ...
    ms_print `ls -r massif.out.* | head -1` | grep Detailed -B50

Чтобы просмотреть подробности, запустите ms_print `ls -r massif.out.* | head -1`

Другие вопросы по тегам