Могу ли я использовать dtrace на OS X 10.5, чтобы определить, какая из моих подпрограмм perl вызывает наибольшее выделение памяти? - PullRequest
9 голосов
/ 03 января 2012

У нас довольно большая база кодов perl.

Некоторые процессы, которые выполняются в течение нескольких часов (задания ETL), внезапно начали потреблять намного больше оперативной памяти, чем обычно.Анализ изменений в соответствующем выпуске - медленный и разочаровывающий процесс.Я надеюсь определить виновника с помощью более автоматизированного анализа.

Нашей рабочей средой является perl 5.14 на Debian squeeze.

Хотя у меня есть доступ ко многим машинам с OS X 10.5.Dtrace и Perl, похоже, прекрасно играют вместе на этой платформе.Кажется, что использование dtrace в Linux требует дополнительной загрузки.Я надеюсь, что шаблоны распределения памяти будут похожи между нашей действующей системой и системой dev OS X - или, по крайней мере, достаточно похожи, чтобы помочь мне найти источник этого нового использования памяти.

Эта слайд-колода:

https://dgl.cx/2011/01/dtrace-and-perl

показывает, как с помощью dtrace показывать количество обращений к malloc через perl sub.Я заинтересован в отслеживании общего объема памяти, выделяемой perl при выполнении каждой подпрограммы в течение жизненного цикла процесса.

Есть какие-нибудь идеи о том, как это можно сделать?

Ответы [ 4 ]

4 голосов
/ 03 января 2012

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

Возможно, вы захотите использовать Valgrind . Есть даже модуль Perl Test :: Valgrind , который поможет настроить файл подавления для вашей сборки Perl, а затем проверить утечки памяти или ошибки в вашем скрипте.

Также есть Devel :: Size , который делает точно , что вы просили, но на основе переменной за переменной, а не по частям.

Вы можете использовать Devel :: Cycle для поиска непреднамеренных циклических ссылок в памяти в сложных структурах данных. В то время как циклическая ссылка не означает, что вы тратите впустую память, когда используете объект, циклические ссылки препятствуют освобождению чего-либо в цепочке до тех пор, пока цикл не прервется.

Devel :: Leak немного более загадочен, чем остальные, но в основном это позволит вам получить полную информацию о любых SV s, которые созданы и не уничтожены между две точки в исполнении вашей программы. Если вы проверите это через дополнительный вызов, вы узнаете любую новую память, выделенную этой подпрограммой.

Вы также можете прочитать раздел perldebguts в руководстве по Perl.

Я не могу больше помочь, потому что каждая кодовая база будет отличаться. Test :: Valgrind будет отлично работать для одних кодовых баз и ужасно для других. Если вы собираетесь попробовать это, я рекомендую вам использовать последнюю доступную версию Valgrind и Perl> = 5.10, так как Perl 5.8 и Valgrind исторически не ладили.

2 голосов
/ 29 февраля 2012

Ответ на вопрос «да».Dtrace может использоваться для анализа использования памяти в процессе perl.

Этот фрагмент кода:

https://github.com/astletron/perl-dtrace-malloc/blob/master/perl-malloc-total-bytes-by-sub.d

отслеживает, как увеличивается использование памяти между вызовом и возвратомкаждый саб в программе.В качестве дополнительного бонуса, dtrace, кажется, сортирует вывод для вас (по крайней мере, в OS X).Круто.

Спасибо всем, кто вмешался. Я сам ответил на этот вопрос, так как вопрос действительно специфичен для dtrace / perl.

2 голосов
/ 04 января 2012

Возможно, вы захотите взглянуть на Память :: Использование и Devel :: Size

Чтобы проверить весь процесс или подпункт:

use Memory::Usage;
my $mu = Memory::Usage->new();

# Record amount of memory used by current process
$mu->record('starting work');

# Do the thing you want to measure
$object->something_memory_intensive();

# Record amount in use afterwards
$mu->record('after something_memory_intensive()');

# Spit out a report
$mu->dump();

Или для проверки конкретных переменных:

use Devel::Size qw(size total_size);

my $size = size("A string");

my @foo = (1, 2, 3, 4, 5);
my $other_size = size(\@foo);

my $foo = {
     a => [1, 2, 3],
     b => {a => [1, 3, 4]}
};
my $total_size = total_size($foo);
1 голос
/ 04 января 2012

Вы можете написать простой модуль отладки, основанный на Devel :: CallTrace , который печатает введенную подпрограмму и текущий объем памяти текущего процесса.(Используя / proc или как угодно.)

...