9

かなり大きなperlコードベースがあります。

複数時間実行される一部のプロセス(ETLジョブ)は、突然、通常よりもはるかに多くのRAMを消費し始めました。関連するリリースの変更の分析は、時間がかかり、苛立たしいプロセスです。より自動化された分析を使用して、原因を特定したいと考えています。

私たちのライブ環境はDebiansqueezeのperl5.14です。

しかし、私は多くのOSX10.5マシンにアクセスできます。Dtraceとperlは、このプラットフォームでうまく連携しているようです。Linuxでdtraceを使用するには、起動にさらに作業が必要なようです。私は、メモリ割り当てパターンがライブシステムと開発OS Xシステムの間で類似していること、または少なくともこの新しいメモリ使用の原因を見つけるのに十分類似していることを望んでいます。

このスライドデッキ:

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

dtraceの使用方法を示しています。perlsubによるmallocへの呼び出し数を示しています。プロセスの存続期間にわたって各サブを実行している間にperlが割り当てるメモリの総量を追跡することに興味があります。

これをどのように行うことができるかについてのアイデアはありますか?

4

4 に答える 4

4

これを行う方法は 1 つではなく、サブごとに行うことが常にメモリ使用量を調べる最善の方法とは限りません。使用できる一連のツールをお勧めします。プログラム全体で機能するツールもあれば、コードの単一セクションまたは単一変数を調べることができるツールもあります。

Valgrindの使用を検討することをお勧めします。Test::Valgrindと呼ばれる Perl モジュールもあります。これは、Perl ビルドの抑制ファイルをセットアップし、スクリプト内のメモリ リークやエラーをチェックするのに役立ちます。

Devel::Sizeもあります。これは、サブごとではなく、変数ごとに、まさにあなたが要求したことを行います。

Devel::Cycleを使用して、複雑なデータ構造で意図しない循環メモリ参照を検索できます。循環参照は、オブジェクトを使用するときにメモリを浪費していることを意味するわけではありませんが、循環参照は、サイクルが壊れるまでチェーン内の何かが解放されるのを防ぎます。

Devel::Leakは他のものよりも少し難解ですが、基本的には、プログラムの実行の 2 つのポイント間で作成され、破棄されていないSVに関する完全な情報を取得できます。サブコール全体でこれを確認すると、そのサブルーチンが割り当てた新しいメモリがわかります。

Perl マニュアルのperldebgutsセクションも読みたいと思うかもしれません。

すべてのコードベースが異なったものになってしまうため、これ以上のことはできません。Test::Valgrind は、一部のコードベースではうまく機能し、他のコードベースではひどく機能します。Perl 5.8 と Valgrind は歴史的にあまりうまくいかなかったため、試してみる場合は、最新バージョンの Valgrind と Perl >= 5.10 を使用することをお勧めします。

于 2012-01-03T17:00:19.837 に答える
2

質問への答えは「はい」です。Dtrace を使用して、perl プロセスのメモリ使用量を分析できます。

このコード スニペット:

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

プログラム内のすべてのサブルーチンの呼び出しと戻りの間でメモリ使用量がどのように増加するかを追跡します。追加のボーナスとして、dtrace は出力をソートするようです (少なくとも OS X では)。涼しい。

質問が本当にdtrace/perlに固有のものであるため、私はこれに自分で答えました。

于 2012-02-29T09:33:52.173 に答える
2

Memory::UsageDevel::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);
于 2012-01-04T12:46:59.580 に答える
1

入力されたサブルーチンと現在のプロセスの現在のメモリ サイズを出力する、Devel::CallTraceに基づいた簡単なデバッグ モジュールを作成できます。(/proc などを使用します。)

于 2012-01-04T13:39:40.860 に答える