Linux: Total swap yang digunakan = swap yang digunakan oleh proses +?

17

Jadi, saya mencoba melakukan penyelidikan tentang dari mana penggunaan swap berasal dari sistem dengan penggunaan swap tinggi:

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

Menambahkan swap yang digunakan per proses:

# 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

Yang memberikan nilai lebih rendah untuk total swap bekas. Di mana sisa ruang swap yang digunakan? Apakah ini memori vmalloc () di dalam kernel? Sesuatu yang lain Bagaimana saya bisa mengidentifikasi itu?

Output dari 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
ninj
sumber
Buffer dan cache disertakan dan mereka tidak terkait dengan proses apa pun.
goldilocks
2
@goldilocks: tidak, itu ada dalam memori fisik. Juga, mereka tidak bertambah.
ninj
Anda benar, saya kira caching barang untuk ditukar akan menjadi semacam gunanya. Namun, saya pikir hal-hal yang ditukar keluar dapat dibiarkan di sana dan dilacak bahkan setelah proses yang dimiliki sudah mati, selama ruang swap itu tidak diperlukan; ini menghemat waktu kemudian jika suatu proses memuat halaman yang sama dan kemudian halaman itu harus ditukar lagi - itu masih ada di swap. Google "swap cache" linux-tutorial.info/modules.php?name=MContent&pageid=314 Ini sejajar dengan bagaimana "cache cache" yang sebenarnya terjadi (barang disimpan dalam memori dari proses yang sekarang tidak berfungsi).
goldilocks
... artinya, lol, bahwa "caching stuff in swap" tidak begitu berguna, hanya saja itu tidak sampai di sana dengan menukar cache RAM keluar.
goldilocks
1
Bukankah jawabannya hanya bahwa kernel dapat bertukar, dan itu tidak termasuk dalam pemrosesan Anda? Khususnya kernel memiliki seluruh tumpukan "ruang pengguna" proses saat ini ... Hanya dugaan saja.
iain

Jawaban:

11

Perbedaan yang Anda amati sebenarnya bukan karena ruang swap tidak diperhitungkan. "(Dihapus)" yang kadang-kadang ditambahkan oleh kernel ke /proc/*/exetautan dihasilkan oleh readlinkdan menyebabkan kesalahan parse dalam skrip awk Anda, dan Anda secara efektif tidak menghitung proses yang binernya tidak lagi ada dalam total Anda.

Beberapa kernel menambahkan kata "(dihapus)" untuk /proc/*/exemenyinkronkan target ketika executable asli untuk proses tidak lagi ada.

Alasan mengapa perintah Anda menunjukkan kurang dari total adalah karena ini. Keluaran readlinkpada tautan semacam itu akan menjadi sesuatu seperti "/ path / ke / bin (dihapus)", yang menyebabkan kesalahan parse awkketika output diganti kembali ke dalam string (tidak seperti tanda kurung dan spasi). Sebagai contoh, lakukan ini:

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

Dan Anda akan melihat beberapa entri dengan "(dihapus)" ditambahkan. Jika Anda melihat penggunaan swap untuk entri ini, totalnya akan cocok dengan perbedaan yang Anda lihat, karena awkkesalahan yang dihasilkan mencegah total mereka dari dihitung dan dimasukkan dalam total akhir.

Jika Anda menjalankan perintah awal tanpa mengarahkan ulang stderr di mana pun, Anda mungkin akan melihat beberapa kesalahan "runaway string constant". Kesalahan itu adalah hasil dari yang di atas dan Anda seharusnya tidak mengabaikannya.

Mengabaikan peningkatan potensial lainnya pada perintah asli Anda, Anda dapat memodifikasinya dengan menghapus "(dihapus)", seperti ini (catatan |awk '{print $1}'ditambahkan ke readlinkoutput):

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"}'

Penggunaan ini awkuntuk memperbaiki output readlinkdapat rusak jika nama berisi spasi - Anda dapat menggunakan sedatau metode apa pun yang Anda inginkan.

Info Bonus

Ngomong-ngomong, Anda hanya bisa menggunakan smem -t. Kolom "Tukar" menampilkan apa yang Anda inginkan.

Sedangkan untuk menghitungnya sendiri, Anda juga bisa mendapatkan informasi ini lebih langsung dari VmSwapbidang di /proc/*/status(smaps membutuhkan beberapa dukungan kernel dan tidak selalu tersedia), dan menghindari keharusan mengarahkan ulang output kesalahan dengan menggunakan pola nama file yang tepat yang menghindari kesalahan untuk memulai dengan:

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" }'

Jika Anda tidak memerlukan biner yang sebenarnya dan dapat menangani hanya dengan memiliki nama proses, Anda bisa mendapatkan semuanya dari 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 }'

Dan akhirnya, jika cukup dengan PID, Anda bisa melakukan semuanya dengan awk:

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

catatan:

Sekarang ini bukan untuk mengatakan bahwa tidak ada perbedaan antara freedan smem(yang terakhir sama dengan skrip Anda). Ada banyak (lihat, misalnya, https://www.google.com/search?q=smem+free , yang memiliki hasil lebih dari cukup di halaman pertama untuk menjawab pertanyaan Anda tentang penggunaan memori). Tetapi tanpa tes yang tepat, situasi khusus Anda tidak dapat diatasi.

Jason C
sumber
5

Swap juga digunakan oleh tmpfs jika kernel membutuhkan lebih banyak ram gratis atau hanya karena tidak digunakan untuk beberapa waktu ... sehingga penggunaan tmpfs apa pun mungkin menggunakan swap.

higuita
sumber
1
Mengapa downvote? Ini benar sekali.
jlliagre