
実行中のプロセスのメモリ リークを見つける方法はありますか? プロセスの開始前にメモリ リークを見つけるために Valgrind を使用できます。GDB を使用して、実行中のプロセスにアタッチできます。実行中のプロセスのメモリ リークをデバッグするにはどうすればよいでしょうか?
答え1
メモリリークの原因をほぼ確実に見つけられる手順は次のとおりです。
メモリ リークの原因となっているプロセスの PID を見つけます。
ps -aux
をキャプチャして
/proc/PID/smaps
、 のようなファイルに保存しますBeforeMemInc.txt
。- メモリが増加するまで待ちます。
- もう一度キャプチャし
/proc/PID/smaps
て保存するとafterMemInc.txt
smaps
1番目と2番目の差を求めますsmaps
。例:diff -u beforeMemInc.txt afterMemInc.txt
メモリが増加したアドレス範囲を書き留めます。例:
beforeMemInc.txt afterMemInc.txt --------------------------------------------------- 2b3289290000-2b3289343000 2b3289290000-2b3289343000 #ADDRESS Shared_Clean: 0 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Clean: 0 kB Private_Dirty: 28 kB Private_Dirty: 36 kB Referenced: 28 kB Referenced: 36 kB Anonymous: 28 kB Anonymous: 36 kB #INCREASE MEM AnonHugePages: 0 kB AnonHugePages: 0 kB Swap: 0 kB Swap: 0 kB KernelPageSize: 4 kB KernelPageSize: 4 kB MMUPageSize: 4 kB MMUPageSize: 4 kB Locked: 0 kB Locked: 0 kB VmFlags: rd wr mr mw me ac VmFlags: rd wr mr mw me ac
GDBを使用して実行中のプロセスのメモリをダンプするか、コアダンプを取得するには、
gcore -o process
実行中のプロセスで gdb を使用して、メモリをファイルにダンプしました。
gdb -p PID dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
ここで、
strings
コマンドまたはを使用してhexdump -C
印刷しますdump_outputfile.dump
strings outputfile.dump
読み取り可能な形式で、ソース コード内でそれらの文字列を検索できるようになります。
漏れを見つけるためにソースを分析します。
答え2
私は思うメムリークスまさにあなたが望むものです。
プログラムを再コンパイルしたり、ターゲット プロセスを再起動することなく、実行中のプロセスのメモリ リークをアタッチしてデバッグします。非常に便利で、実稼働環境に適しています。
GNU/Linux および FreeBSD で動作します。
注記:私は著者ですので、どんな提案でも歓迎します。
== 編集 ==
私は別のツールも書きましたリブリークLD_PRELOAD によってメモリ関数をフックします。
対象プログラムを変更する必要はありません。LD_PRELOAD で処理を再開する必要がありますが、実行中に検出を有効/無効にすることができます。
シグナルトラップがないため、パフォーマンスへの影響は大幅に少なくなります。
同様のツール (mtrace など) と比較すると、疑わしいメモリ リーク ポイントで完全なコール スタックを出力します。
答え3
答え4
IBMの清めるおそらく最も古く、最も洗練されたツールです。メモリ リークの原因となるコードの行番号にフラグを付けます。