그래서 스왑 사용률이 높은 시스템에서 스왑 사용의 위치를 조사하려고합니다.
# 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
답변
당신이 관찰하고있는 차이점은 실제로 스왑 공간이 고려되지 않았기 때문이 아닙니다. 커널이 때때로 추가하는 “(삭제)”/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를 다른 곳으로 리디렉션하지 않고 원래 명령을 실행하면 몇 가지 “runaway string constant”오류가 표시 될 수 있습니다. 이러한 오류는 위의 결과이므로 무시해서는 안됩니다.
원래 명령의 다른 잠재적 개선 사항을 무시하고 다음과 같이 “(삭제됨)”을 제거하여 수정할 수 있습니다 ( 출력에 |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
. “스왑”열에 원하는 내용이 표시됩니다.
그러나 직접 계산하는 경우 (Smaps는 일부 커널 지원이 필요하고 항상 사용 가능한 것은 아닙니다) 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 참조 ). 첫 페이지에 메모리 사용량에 대한 질문에 대한 답변이 충분합니다. 그러나 적절한 테스트가 없으면 특정 상황을 해결할 수 없습니다.
답변
스왑은 커널에 더 많은 여유 램이 필요하거나 단순히 한동안 사용되지 않아서 tmpfs에 의해 사용되므로 tmpfs 사용법은 스왑을 소비 할 수 있습니다.