実行中のプロセスのメモリ リークを見つけるにはどうすればよいでしょうか?

実行中のプロセスのメモリ リークを見つけるにはどうすればよいでしょうか?

実行中のプロセスのメモリ リークを見つける方法はありますか? プロセスの開始前にメモリ リークを見つけるために Valgrind を使用できます。GDB を使用して、実行中のプロセスにアタッチできます。実行中のプロセスのメモリ リークをデバッグするにはどうすればよいでしょうか?

答え1

メモリリークの原因をほぼ確実に見つけられる手順は次のとおりです。

  1. メモリ リークの原因となっているプロセスの PID を見つけます。

    ps -aux
    
  2. をキャプチャして/proc/PID/smaps、 のようなファイルに保存しますBeforeMemInc.txt

  3. メモリが増加するまで待ちます。
  4. もう一度キャプチャし/proc/PID/smapsて保存するとafterMemInc.txt
  5. smaps1番目と2番目の差を求めますsmaps。例:

    diff -u beforeMemInc.txt afterMemInc.txt

  6. メモリが増加したアドレス範囲を書き留めます。例:

       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
    
  7. GDBを使用して実行中のプロセスのメモリをダンプするか、コアダンプを取得するには、gcore -o process

  8. 実行中のプロセスで gdb を使用して、メモリをファイルにダンプしました。

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
    
  9. ここで、stringsコマンドまたはを使用してhexdump -C印刷しますdump_outputfile.dump

    strings outputfile.dump
    
  10. 読み取り可能な形式で、ソース コード内でそれらの文字列を検索できるようになります。

  11. 漏れを見つけるためにソースを分析します。

答え2

私は思うメムリークスまさにあなたが望むものです。

プログラムを再コンパイルしたり、ターゲット プロセスを再起動することなく、実行中のプロセスのメモリ リークをアタッチしてデバッグします。非常に便利で、実稼働環境に適しています。

GNU/Linux および FreeBSD で動作します。

注記:私は著者ですので、どんな提案でも歓迎します。

== 編集 ==

私は別のツールも書きましたリブリークLD_PRELOAD によってメモリ関数をフックします。

対象プログラムを変更する必要はありません。LD_PRELOAD で処理を再開する必要がありますが、実行中に検出を有効/無効にすることができます。

シグナルトラップがないため、パフォーマンスへの影響は大幅に少なくなります。

同様のツール (mtrace など) と比較すると、疑わしいメモリ リーク ポイントで完全なコール スタックを出力します。

答え3

Linuxでは、mtraceプログラムでは、コードの変更になります。

OpenBSDでは、malloc 統計

Googleのリークチェッカーも一見の価値があるかもしれません。mtrace とは異なり、LD_PRELOAD再コンパイルを回避するために使用できる可能性があります。

答え4

IBMの清めるおそらく最も古く、最も洗練されたツールです。メモリ リークの原因となるコードの行番号にフラグを付けます。

関連情報