そこで、スワップ使用量が高いシステムでスワップ使用量がどこで発生するのかを調べてみました。
# 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()メモリがありますか?他にはありませんか?どうやって識別できますか?
メモリ情報出力:
# 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
答え1
観察された違いは、実際にはスワップスペースを考慮していないためではありません。カーネルが時々リンクに追加する/proc/*/exe
「(削除済み)」は awk スクリプトによって出力され、readlink
awk スクリプトで解析エラーを引き起こし、実際にはバイナリが完全に存在しなくなったプロセスを計算しません.
/proc/*/exe
一部のカーネルは、プロセスの元の実行可能ファイルが存在しなくなったときにシンボリックリンクターゲットに「(削除済み)」という単語を追加します。
コマンドが合計より少なく表示されるのは、これです。これらのリンクの出力は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
「swap」列を使用して必要なものを表示できます。
ただし、直接計算する場合は、フィールドからVmSwap
この情報を直接取得することもできます/proc/*/status
(スマップにはいくつかのカーネルサポートが必要であり、常に使用できるわけではありません)、適切なファイル名パターンを使用してエラー出力をリダイレクトすることを避けることができます。
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、最初のページの結果は、メモリ使用量に関する質問に答えるのに十分です。しかし、適切なテストがなければ、特定の状況を解決する方法はありません。
答え2
tmpfs はまた、カーネルに余分な空きメモリが必要になるか、単に使用されていないためスワップを使用するため、すべての tmpfs の使用はスワップを消費する可能性があります。