Linux: Tổng số trao đổi được sử dụng = trao đổi được sử dụng bởi các quy trình +?


17

Vì vậy, tôi đang cố gắng thực hiện một số điều tra về việc sử dụng trao đổi đến từ đâu trong một hệ thống có mức sử dụng trao đổi cao:

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

Thêm trao đổi được sử dụng cho mỗi quá trình:

# 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

Cung cấp một giá trị thấp hơn cho tổng số trao đổi được sử dụng. Trường hợp hoán đổi được sử dụng còn lại ở đâu? Có phải bộ nhớ vmalloc () 'bên trong kernel? Thứ gì khác? Làm thế nào tôi có thể xác định nó?

Đầu ra của 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

Bộ đệm và bộ đệm được bao gồm và chúng không được liên kết với bất kỳ quá trình.
goldilocks

2
@goldilocks: không, đó là trong bộ nhớ vật lý. Ngoài ra, họ không thêm.
ninj

Bạn nói đúng, tôi đoán những thứ lưu trữ để trao đổi sẽ là vô nghĩa. Tuy nhiên, tôi nghĩ rằng những thứ bị tráo đổi có thể bị bỏ lại ở đó và được theo dõi ngay cả sau khi quy trình sở hữu không còn tồn tại, miễn là không gian hoán đổi đó là không cần thiết; điều này giúp tiết kiệm thời gian sau này nếu một quá trình tải cùng một trang và sau đó trang đó phải được hoán đổi một lần nữa - nó vẫn còn ở đó trong trao đổi. Google "hoán đổi bộ đệm" linux-tutorial.info/modules.php?name=MContent&pageid=314 Điều này tương tự như cách "bộ đệm bộ đệm" thực tế xuất hiện (đó là thứ được lưu trong bộ nhớ từ các quy trình không còn tồn tại).
goldilocks

... có nghĩa là, lol, rằng "bộ nhớ đệm trong trao đổi" không phải là quá vô nghĩa, chỉ là nó không đạt được điều đó bằng cách hoán đổi bộ nhớ cache RAM.
goldilocks

1
Không phải câu trả lời là kernel có thể trao đổi và điều đó không có trong quá trình xử lý của bạn? Đặc biệt, hạt nhân có cả đống quá trình "không gian người dùng" hiện nay ... Chỉ là một phỏng đoán được xem xét.
iain

Câu trả lời:


11

Sự khác biệt mà bạn đang quan sát không thực sự là do không gian hoán đổi không được tính đến. "(Đã xóa)" mà hạt nhân đôi khi gắn vào /proc/*/execác liên kết là đầu ra readlinkvà gây ra lỗi phân tích cú pháp trong tập lệnh awk của bạn và bạn thực sự không tính các quy trình mà các nhị phân không còn hiện diện trong tổng số của bạn.

Một số hạt nhân nối từ "(đã xóa)" vào /proc/*/execác mục tiêu liên kết tượng trưng khi thực thi ban đầu cho quy trình không còn tồn tại.

Lý do lệnh của bạn hiển thị ít hơn tổng số là vì điều này. Đầu ra của readlinkcác liên kết như vậy sẽ là một cái gì đó như "/ path / to / bin (đã xóa)", gây ra lỗi phân tích cú pháp awkkhi đầu ra được thay thế trở lại vào chuỗi (nó không giống như dấu ngoặc đơn và dấu cách). Ví dụ: làm điều này:

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

Và bạn sẽ thấy một vài mục có "(đã xóa)" được nối thêm. Nếu bạn đã xem việc sử dụng trao đổi cho các mục này, tổng số của chúng sẽ khớp với sự khác biệt mà bạn thấy, vì các awklỗi kết quả sẽ ngăn tổng số của chúng được tính và đưa vào tổng cuối cùng.

Nếu bạn chạy lệnh ban đầu của mình mà không chuyển hướng stderr ở bất cứ đâu, có thể bạn sẽ nhận thấy một vài lỗi "hằng chạy chuỗi". Những lỗi đó là kết quả của những điều trên và bạn không nên bỏ qua chúng.

Bỏ qua các cải tiến tiềm năng khác cho lệnh ban đầu của bạn, bạn có thể sửa đổi nó bằng cách xóa "(đã xóa)", như thế này (ghi chú |awk '{print $1}'thêm vào readlinkđầu ra):

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

Việc sử dụng này awkđể sửa lỗi đầu ra readlinkcó thể bị sedhỏng nếu tên chứa khoảng trắng - bạn có thể sử dụng hoặc bất kỳ phương thức nào bạn thích.

Thông tin thưởng

Nhân tiện, bạn chỉ có thể sử dụng smem -t. Cột "Hoán đổi" hiển thị những gì bạn muốn.

Tuy nhiên, để tự mình tính toán, bạn cũng có thể lấy thông tin này trực tiếp hơn từ VmSwaptrường trong /proc/*/status(smaps yêu cầu một số hỗ trợ kernel và không phải lúc nào cũng có sẵn) và tránh phải chuyển hướng đầu ra lỗi bằng cách sử dụng mẫu tên tệp thích hợp để tránh lỗi bắt đầu bằng:

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

Nếu bạn không cần nhị phân thực tế và có thể xử lý chỉ cần có tên quy trình, bạn có thể nhận mọi thứ từ 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 }'

Và cuối cùng, nếu chỉ cần có đủ các PID, bạn có thể thực hiện tất cả với awk:

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

Ghi chú:

Bây giờ điều này không có nghĩa là không có sự khác biệt giữa freesmem(cái sau giống với kịch bản của bạn). Có rất nhiều (xem, ví dụ: https://www.google.com.vn/search?q=smem+free , có nhiều kết quả trên trang đầu tiên để trả lời câu hỏi của bạn về việc sử dụng bộ nhớ). Nhưng không có một bài kiểm tra thích hợp, tình huống cụ thể của bạn không thể được giải quyết.


5

Hoán đổi cũng được sử dụng bởi các tmpfs nếu kernel cần thêm ram miễn phí hoặc đơn giản là vì nó không được sử dụng trong một thời gian ... vì vậy bất kỳ việc sử dụng tmpfs nào cũng có thể tiêu thụ trao đổi.


1
Tại sao các downvote? Điều này là hoàn toàn chính xác.
jlliagre
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.