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

맞습니다. 스왑 할 캐싱은 무의미합니다. 그러나, 스왑 공간이 달리 필요하지 않는 한, 스왑 아웃 된 것들이 남아 있고 소유 한 프로세스가 없어진 후에도 추적 될 수 있다고 생각합니다. 이렇게하면 프로세스가 동일한 페이지를로드 한 다음 해당 페이지를 다시 스왑해야하는 경우 시간이 절약됩니다. 아직 스왑 상태입니다. 구글 "스왑 캐시" 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를 다른 곳으로 리디렉션하지 않고 원래 명령을 실행하면 몇 가지 "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

노트 :

지금 이것은 차이가없는 것을 말하는 것이 아니다 freesmem(후자의 존재 스크립트와 동일). 메모리 가 충분합니다 (예 : https://www.google.com/search?q=smem+free 참조 ). 첫 페이지에 메모리 사용량에 대한 질문에 대한 답변이 충분합니다. 그러나 적절한 테스트가 없으면 특정 상황을 해결할 수 없습니다.


5

스왑은 커널에 더 많은 여유 램이 필요하거나 단순히 한동안 사용되지 않아서 tmpfs에 의해 사용되므로 tmpfs 사용법은 스왑을 소비 할 수 있습니다.


1
왜 downvote입니까? 이것은 절대적으로 맞습니다.
jlliagre
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.