Как получить высшую отметку использования памяти на 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`