Linux:使用される合計スワップ=プロセスで使用されるスワップ+?


17

だから、私はスワップ使用率が高いシステムでスワップ使用がどこから来るのかについていくつかの調査をしようとしています:

# free
             total       used       free     shared    buffers     cached
Mem:        515324     508800       6524          0       4852      27576
-/+ buffers/cache:     476372      38952
Swap:       983032     503328     479704

プロセスごとに使用されるスワップを追加する:

# for proc in /proc/*; do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe`'"}'; done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'
0       /bin/gawk
0       /bin/sort
0       /usr/bin/readlink
28      /sbin/xxxxxxxx
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
56      /sbin/mingetty
56      /sbin/mingetty
60      /xxxxxxxxxxx
60      /usr/sbin/xxx
84      /usr/sbin/xxx
108     /usr/bin/xxx
168     /bin/bash
220     /sbin/init
256     /sbin/rsyslogd
352     /bin/bash
356     /bin/bash
360     /usr/sbin/sshd
496     /usr/sbin/crond
672     /usr/sbin/sshd
12972   /opt/jdk1.6.0_22/bin/java
80392   /usr/libexec/mysqld
311876  /opt/jdk1.6.0_22/bin/java
408780  Total

合計使用スワップの値が低くなります。残りの使用済みスワップスペースはどこにありますか?カーネル内のvmalloc()されたメモリですか?他に何か?どうすれば識別できますか?

meminfoの出力:

# cat /proc/meminfo 
MemTotal:       515324 kB
MemFree:          6696 kB
Buffers:          5084 kB
Cached:          28056 kB
SwapCached:     157512 kB
Active:         429372 kB
Inactive:        65068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       515324 kB
LowFree:          6696 kB
SwapTotal:      983032 kB
SwapFree:       478712 kB
Dirty:             100 kB
Writeback:           0 kB
AnonPages:      399456 kB
Mapped:           8792 kB
Slab:             7744 kB
PageTables:       1820 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   1240692 kB
Committed_AS:  1743904 kB
VmallocTotal:   507896 kB
VmallocUsed:      3088 kB
VmallocChunk:   504288 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     4096 kB

バッファとキャッシュが含まれており、どのプロセスにも関連付けられていません。
goldilocks

2
@goldilocks:いいえ、物理メモリにあります。また、それらは加算されません。
-ninj

あなたは正しい、私はスワップするものをキャッシュすることは無意味なものだと思う。ただし、スワップ領域が必要ない限り、スワップアウトされたものは、所有しているプロセスが機能しなくなった後でもそこに残され、追跡される可能性があると思います。プロセスが同じページをロードし、そのページを再度スワップアウトする必要がある場合、これは後で時間を節約します-それはまだスワップ内にまだあります。Googleの「スワップキャッシュ」linux-tutorial.info/modules.php?name=MContent&pageid=314 これは、実際の「キャッシュキャッシュ」がどのようになるかを示しています(現在は無効なプロセスからメモリに保存されているものです)。
-goldilocks

...つまり、「スワップ内のキャッシュ」はあまり意味がなく、RAMキャッシュをスワップアウトしてもそこに到達しないということです。
goldilocks

1
答えは、カーネルがスワップできるということだけではなく、それはあなたの処理に含まれていませんか?特に、カーネルは最近、「ユーザー空間」プロセスのヒープ全体を持っています。
iain

回答:


11

あなたが観察している違いは、実際にはスワップスペースが考慮されていないためではありません。カーネルが/proc/*/exeリンクに追加することがある「(削除済み)」が出力さreadlinkれ、awkスクリプトで解析エラーが発生します。また、バイナリが合計に存在しないプロセスを事実上カウントしていません。

一部のカーネル/proc/*/exeは、プロセスの元の実行可能ファイルがなくなったときに、「(削除済み)」という単語をsymlinkターゲットに追加します。

コマンドが合計よりも少ないのは、このためです。このreadlinkようなリンクでの出力は「/ path / to / bin(削除済み)」のようなものにawkなり、出力が文字列に戻されたときに解析エラーが発生します(括弧やスペースが好きではありません)。たとえば、次のようにします。

for a in /proc/*/exe ; do readlink $a ; done | grep deleted

また、「(削除済み)」が追加されたエントリがいくつか表示されます。これらのエントリのスワップ使用量を調べた場合、結果のawkエラーにより合計が計算されて最終合計に含まれないため、合計が表示される不一致と一致します。

stderrをどこにもリダイレクトせずに元のコマンドを実行すると、おそらくいくつかの「暴走ストリング定数」エラーに気付くでしょう。これらのエラーは上記の結果であり、無視するべきではありません。

元のコマンドに対する他の潜在的な改善を無視して、次のように「(削除済み)」を削除することで変更できます(出力に|awk '{print $1}'追加された注readlink):

for proc in /proc/*; \
  do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe|awk '{print $1}' `'" }'; \
done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'

awkの出力を修正するためのこの使用はreadlink、名前にスペースが含まれている場合に壊れる可能性があります-使用するsedか、任意の方法を使用できます。

ボーナス情報

ちなみに、あなただけを使用することができますsmem -t。「スワップ」列には、必要なものが表示されます。

ただし、自分で計算する場合は、VmSwapフィールドから直接この情報を取得することもできます/proc/*/status(smapsはいくつかのカーネルサポートを必要とし、常に利用可能であるとは限りません)。開始するエラー:

for proc in /proc/[0-9]*; do \
  awk '/VmSwap/ { print $2 "\t'`readlink $proc/exe | awk '{ print $1 }'`'" }' $proc/status; \
done | sort -n | awk '{ total += $1 ; print $0 } END { print total "\tTotal" }'

実際のバイナリを必要とせず、プロセス名だけを扱うことができる場合は、以下からすべてを取得できますstatus

for a in /proc/*/status ; do \
  awk '/VmSwap|Name/ { printf $2 " " } END { print "" }' $a ; \
done | awk '{ total+=$2 ; print $0 } END { print "Total " total }'

そして最後に、PIDがあれば十分な場合は、次の方法ですべてを実行できますawk

awk '/VmSwap/ { total += $2; print $2 "\t" FILENAME } END { print total "\tTotal" }' /proc/*/status

注意:

これは、freeとの間に違いがないと言うことではありませんsmem(後者はスクリプトと同じです)。たくさんあります(たとえば、https://www.google.com/search?q = smem + freeを参照してください。最初のページには、メモリ使用量に関する質問に答えるのに十分な結果があります)。しかし、適切なテストがなければ、特定の状況に対処することはできません。


5

スワップは、カーネルがより多くの空きRAMを必要とする場合、または単にしばらく使用されないために、tmpfsによっても使用されます。したがって、tmpfsを使用するとスワップが消費される可能性があります。


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