メモリリークを検出する方法


16

現在のubuntuシステムでより大きなメモリリークがあるようです

奇妙なEclipseメモリエラー(/ubuntu/148998/eclipse-constant-different-out-of-memory-errors)を報告した後、今日コンソールで「メモリ不足」エラーメッセージを取得し始めました。入力などの簡単なタスクを行うsudo -s-または-free -m

「free -m」と入力すると、RAMが700Mから900Mに急速に増加し、数秒で2000Mのサイズにまで増加する様子が繰り返し表示されました(でメモリを解放した後echo 3 > /proc/sys/vm/drop_caches

Eclipseが原因ではないので、プロセスを完全に終了しましたが、RAMはまだ上がっていました。リークの原因を検出する方法はありますか?apt-get update失敗したためにシステムを更新することもできません(おそらくメモリ不足のため)

を使用して Ubuntu 11.10


クレイジーではないのでとても嬉しいです。13.10にアップグレードしてから同じ問題が発生しましたが、11.10で問題が発生したことを覚えています。質問は次のとおりです。CrashPlanを使用していますか?私はそれをそれに絞り込んでいるようです、私はそれを修正する方法がわかりません。メモリの調整を試しましたが、機能しません。それがあなたにいくつかの手がかりを与えることを願っています
半初心者

カーネルにキャッシュを強制的にドロップしても意味がありません。それ以外の場合は、物理メモリがさらに必要になるとすぐに、それらはフラッシュされ、スペースが解放されます。キャッシュされていないオブジェクトは非常に低速のセカンダリストレージから取得する必要があるため、それらを強制的にフラッシュすると、全体的なパフォーマンスに悪影響を与える可能性があります。空きメインメモリは決して良いことではありません。これは、悪いキャッシュ管理の兆候または非常に軽い使用のいずれかです。
デビッドフォースター14年

回答:


9

memprofは、メモリ使用量をプロファイリングし、メモリリークを見つけるためのツールです。プログラム内の各関数によって割り当てられたメモリ量のプロファイルを生成できます。また、メモリをスキャンして、割り当てたがどこからも参照されなくなったブロックを見つけることができます。

memprofは、ライブラリをプリロードすることで機能し、Cライブラリのメモリ割り当て関数をオーバーライドします。プログラムを再コンパイルする必要はありません。

memprof

出典:Ubuntuマニュアル


11

まず、十分な空き容量がある一時フォルダーを使用できるようにしてください。次のコマンドは、数GBのサイズのダンプを作成します。

次のコマンドを使用して、新しいtmpフォルダーを作成できます。/tmp十分なスペースがある別のファイルシステムに変更したい場合があります

TMPDIR=$(mktemp -d -t -p /tmp)

メモリリークを見つける手順

  1. メモリリークの原因となっているプロセスのPIDを見つけ(使用htop可能な場合などに使用することもできます)、次の変数に格納します。pid

    ps -aux
    
  2. PIDが変数pidで使用できる場合、を使用してメモリ消費をキャプチャし、/proc/$pid/smapsなどのファイルに保存できますbeforeMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/beforeMemInc.txt
    
  3. メモリ消費が増加するまでしばらく待ちます。
  4. /proc/$pid/smaps再度キャプチャして、名前を付けて保存しますafterMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/afterMemInc.txt
    
  5. first smapsと2ndの違いを見つけるsmaps、例えば

    diff -u $TMPDIR/beforeMemInc.txt $TMPDIR/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 $TMPDIR/process $PID
    
  8. 実行中のプロセスでgdbを使用して、メモリをファイルにダンプしました。

    cd $TMPDIR
    gdb -p $pid
    dump memory memory.dump 0x2b3289290000 0x2b3289343000
    
  9. ここで、stringsコマンドを使用するかhexdump -Cmemory.dump

    strings memory.dump
    

    これから、ソースコード内のこれらの文字列を見つけるのに役立つ読み取り可能な情報を取得します。

  10. ソースを分析してリークを見つけます。

私はDockerコンテナにいますcat /proc/2882/smaps > /tmp/before.txt。ステップ2で実行すると、アクセス許可拒否エラーが表示されます。どうしたのですか?
デヴィー

8

drop_cacheトリックはメモリを解放せず、キャッシュをリセットします。用途のPSのコマンドを使用するには、より多くのメモリを使用するプロセスを識別したい場合。

たとえば、常駐メモリユーザーの上位15人のリストを監視します。

$ watch "ps --sort -rss -eo pid,pmem,rss,vsz,comm | head -16"
  PID %MEM   RSS    VSZ COMMAND
 2590 13.4 136892 825000 firefox
 1743 10.7 109020 300780 Xorg
 2067  8.5 86764 1118140 unity-2d-shell
 3307  4.1 42560 627780 unity-2d-spread
 2068  2.9 29904 617644 unity-2d-panel
 2092  2.5 25524 1291204 nautilus
 2457  1.9 20292 530276 gnome-terminal
 2351  1.9 20016 821488 unity-scope-vid
 2161  1.9 19476 531968 unity-panel-ser
 2034  1.7 18256 759716 gnome-settings-
 2074  1.5 16176 518016 nm-applet
 2273  1.5 15452 580416 unity-lens-vide
 2051  1.4 15112 524260 metacity
 2395  1.2 12836 407336 update-notifi

共有メモリの予約も確認できますが、セグメントの所有者のみがわかります。

Pmapの割り当て:

$ ls -l /run/shm
total 272
-r-------- 1 ed      ed      67108904 Nov 29 18:17 pulse-shm-1884617860
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-2352897759
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3444873503
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3485341848
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-535843976
-r-------- 1 ed      ed      67108904 Nov 29 19:12 pulse-shm-789046959
-r-------- 1 ed      ed      67108904 Nov 29 18:38 pulse-shm-863909656

$ df /run/shm 
Filesystem     1K-blocks  Used Available Use% Mounted on
none              509332   272    509060   1% /run/shm

予約済みの割り当ては、実際に割り当てられたページよりもはるかに高いことに注意してください(df 'used')

System Vの割り当て:

$ ipcs -m 

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 294912     ed         700        122880     2          dest         
0x00000000 327681     ed         700        4823040    2          dest         
0x00000000 491522     ed         600        393216     2          dest         
0x00000000 589827     ed         700        4578120    2          dest         
0x00000000 425988     ed         700        27852      2          dest         
0x00000000 458757     ed         600        393216     2          dest         

編集:に渡し--sort -rssps、メモリ使用量が最も多いプロセスを取得する必要があります。そうでない場合、プロセスリストは数値が大きくなるようにソートされ、メモリ使用量が最も少ないプロセスになります


5

私は、メモリリークメッセージを絶えず吐き出す古いマシンを使用しています。

root@:~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1523        374        131         32        588
-/+ buffers/cache:        902        995
Swap:         1942        480       1462

私のスクリプト:

sync; sudo echo 3 > /proc/sys/vm/drop_caches

それに名前を付けた cache.sh

root@~# ./cache.sh
root@~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1106        791        126          1        207
-/+ buffers/cache:        897       1000
Swap:         1942        480       1462

あなたは私が374 MBまで下がって、走って、sync; sudo echo 3 > /proc/sys/vm/drop_cachesそして417 MBを取り戻したことを見ることができます。一つは、することができますcron、それは5分ごとに実行するか、単にターミナルのオープンを持っていて、パフォーマンスの低下を見たときにそれを実行します。はい、マシンにメモリを追加する必要があります...


書式設定が問題のようで、修正方法がわからない
Warpig 14年

1
投稿の下にある編集リンクを使用します。書式設定ツールバーと、Markdown書式設定ヘルプにリンクするテキスト領域の上にオレンジ色の疑問符があります
デビッドフォースター14年

質問に対する私の最近のコメントを見てください。キャッシュをフラッシュしてドロップすることでメインメモリを解放するという考えは見当違いであり、私はその結論だけではないことを知っています。
デビッドフォースター14年

感謝します、デビッド...キャッシュのフラッシュ/ドロップが間違っていることに同意します...しかし、何かがハングアップして、マシンがフリーズ/ロックアップします... ..
ワーピッグ14

3

memstatは、各ブロックで使用されているメモリ量と、ロードされたライブラリで使用されているメモリ量を表示する優れたツールでもあります。最良のツールではありませんが、詳細と統計を収集するために使用する価値があります。

memstat -w -p pid 使用するのに適したコマンドです。


1
リンクが壊れている、私はこれは良いと思う
-vladkras

1

私は同様の問題を抱えていましたが、非常に奇妙な解決策がありました。

いくつかの未知の理由で、ラップトップのセットアップにメールサーバーがあり、実行されていましたが、なぜそれがあったのかわかりません...しかし、サービスを停止し、ラップトップのソフトウェアがddos攻撃を受けていることがわかりました。その後、すべてが正常でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.