Linux에서 "손실된" 메모리 사용량 추적

Linux에서 "손실된" 메모리 사용량 추적

Arch 3.6.7 x86_64 커널에서 시스템의 메모리 사용량을 계산하려고 하는데 보면 볼수록 구멍(사용된 메모리 계산에 구멍이 없는 사용량)이 있는 것을 볼 수 있습니다. ).

새롭게 시작된 시스템입니다. 간단하게 유지하기 위해 systemd 및 sshd 외에는 실행되는 것이 많지 않습니다.

$ ps aux | sort -n -k6
...
root       316  0.0  0.0   7884   812 tty1     Ss+  14:37   0:00 /sbin/agetty --noclear tty1 38400
matt       682  0.0  0.0  24528   820 pts/0    S+   15:09   0:00 sort -n -k6
dbus       309  0.0  0.0  17280  1284 ?        Ss   14:37   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
matt       681  0.0  0.0  10808  1364 pts/0    R+   15:09   0:00 ps aux
root       308  0.0  0.0  26060  1516 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-logind
root       148  0.0  0.0  25972  1692 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-udevd
matt       451  0.0  0.0  78180  2008 ?        S    14:37   0:00 sshd: matt@pts/0
root       288  0.0  0.0  39612  2708 ?        Ss   14:37   0:00 /usr/sbin/sshd -D
matt       452  0.0  0.0  16452  3248 pts/0    Ss   14:37   0:00 -bash
root         1  0.0  0.0  32572  3268 ?        Ss   14:37   0:00 /sbin/init
root       299  0.0  0.0  69352  3604 ?        Ss   14:37   0:00 /usr/sbin/syslog-ng -F
root       449  0.0  0.0  78040  3800 ?        Ss   14:37   0:00 sshd: matt [priv]
root       161  0.0  0.0 358384  9656 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-journald

내가 찾을 수 있는 가장 자세한 메모리 정보는 다음과 같습니다.이것이로 인해 2007년부터 프로세스의 공통 커널 계정에 Pss 필드가 추가된 것으로 보이지만 Python 코드는 이전 커널용이며 불행히도 그 이후로 /proc/k* 파일 중 일부가 사라졌습니다. 이것/proc/메모리 정보문서도 도움이 되지만 약간 오래되었습니다.

여기 제가 본 데모가 있습니다.

# cat /proc/meminfo
MemTotal:       16345780 kB
MemFree:        16129940 kB
Buffers:           10360 kB
Cached:            48444 kB
SwapCached:            0 kB
Active:            24108 kB
Inactive:          46724 kB
Active(anon):      12104 kB
Inactive(anon):     3616 kB
Active(file):      12004 kB
Inactive(file):    43108 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         11996 kB
Mapped:            16372 kB
Shmem:              3696 kB
Slab:              25092 kB
SReclaimable:      11716 kB
SUnreclaim:        13376 kB
KernelStack:         928 kB
PageTables:         2428 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8172888 kB
Committed_AS:      34304 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      372788 kB
VmallocChunk:   34359362043 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       12288 kB
DirectMap2M:    16680960 kB

사용한 것을 합산하면 다음과 같습니다.

MemTotal - MemFree - Buffers - Cached = Used
16345780 - 16129940 - 10360 - 48444 = 157036

모든 활성/비활성은 일부 페이지(전체는 아님)에 적용되는 카운터로 나타나므로 다른 곳에서도 중복되는 개수가 있을 수 있습니다.

Active + Inactive = Used
46724  + 24108    = 70832 (not quite)

여기서 Committed_AS는 /proc/*/smaps의 공유 파일을 뺀 사용자 공간 개인/공유 메모리의 합계를 면밀히 추적하는 것으로 보입니다.PSS를 이용하세요아직 대기열이 있다는 점을 고려하면. (흥미롭게도 32비트 데비안 2.6.32-5-686에서는 훨씬 더 큰 Commited_AS를 얻었습니다.)

AnonPages + Mapped + Commited_AS = Userspace?
11996     + 16372  + 34304       = 62672

슬래브는 /proc/slabinfo와 인라인입니다.

Slab +  Shmem + KernelStack + PageTables = Kernelspace?
25092 + 3696  + 928         + 2428       = 32144

Userspace? + Kernelspace? = Used?
62672      + 32144        = 94816

그래서 ~ 63M 짧습니다. 나는 갑자기 커널과 로드된 모든 모듈에 약간의 MB가 없다는 것을 깨달았습니다. 하지만 보드가 많은 것을 포함하는 것 같아서 누락된 것이 있으면 이것이 ~60Mb에 해당하는지 확실하지 않습니다.

63은 Active+Inactive 숫자에 다소 가깝지만 그다지 옳다고 느껴지지는 않습니다.

그렇다면 이 마법의 공식을 아는 사람이 있나요? 그렇지 않고 내가 보고 있는 다이어그램이 올바른 경우 조사할 수 있는 메모리 할당의 회색 영역은 무엇입니까?

리눅스가 내 메모리를 잡아먹은 것 같아요! 일반적으로 청구되는 것보다 적은 비율이지만 =)

편집하다Committed_AS는 커밋된 내용의 99.9%를 처리하는 데 필요한 메모리 양에 대한 커널의 추측이므로 실제로 할당된 숫자는 아닙니다. AnonPages+Mapped는 그 구성 요소이므로 이제 약 100MB의 더 큰 구멍이 남습니다.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages 및 Mapped는 주로 PSS/Shared를 고려하여 /proc/[0-9]*/smaps wgen에서 anon/mapped 정보를 추적합니다.

예약된 영역은 전체 메모리에서 가져온 블록에 모두 맞는 것 같습니다.

free메모리는 16345032Kb입니다.
총 시스템 메모리는 16777216Kb입니다.
PCI '홀' - lspci -v 266520K = 16510696K
Bios 예약됨 - dmesg 92793K = 16417903K

편집 2 나는 원래 상자 내부에서 실행되는 VM에서는 이러한 추가 메모리 사용량이 없음을 발견했습니다 /proc/meminfo. 그래서 차이점이 무엇인지 살펴보기 시작했습니다. 최종적으로 사용 가능한 총 물리적 메모리의 증가는 사용된 메모리의 증가와 일치하는 것으로 나타났습니다.

phys 16GB used>144508     vm>50692      user>21500      kern>26428      u+ktot>47928
vm   64MB used>24612      vm>31140      user>14956      kern>14440      u+ktot>29396
vm  256MB used>26316      vm>35260      user>14752      kern>14780      u+ktot>29532
vm    1GB used>33644      vm>35224      user>14936      kern>14772      u+ktot>29708
vm    2GB used>41592      vm>35048      user>14736      kern>15056      u+ktot>29792
vm    4GB used>57820      vm>35232      user>14780      kern>14952      u+ktot>29732
vm    8GB used>82932      vm>36912      user>15700      kern>15388      u+ktot>31088
vm   12GB used>110072     vm>35248      user>14812      kern>15624      u+ktot>30436
vm   15GB used>122012     vm>35424      user>14832      kern>15824      u+ktot>30656

계산 결과 메모리 1GB당 약 8Mb가 할당됩니다. 커널에 메모리 맵이 있을 수도 있지만... 부팅 시 설정되지 않고 메모리가 할당될 때만 증가한다고 생각합니다.

이러한 추세가 계속된다면 누구든지 bigmem 머신에 액세스할 수 있는지 알아보는 것이 흥미로울까요?

답변1

"프로세스에서 사용하는 메모리"는아니요최신 운영 체제의 명확한 개념입니다. 측정할 수 있는 것은 프로세스의 주소 공간 크기(SIZE)와 상주 세트 크기(RSS, 현재 메모리에 있는 주소 공간의 페이지 수)입니다. RSS의 일부는 공유됩니다(메모리에 있는 대부분의 프로세스는 다양한 기타 공유 라이브러리뿐만 아니라 glibc의 복사본을 공유합니다. 동일한 실행 파일을 실행하는 여러 프로세스는 RSS를 공유하고, 포크된 프로세스는 읽기 전용 데이터를 공유하는 등). 아직 수정되지 않은 데이터(상위 데이터 읽기 및 쓰기) 반면, 페이지 테이블, 커널 버퍼, 커널 스택 등 커널이 프로세스를 위해 사용하는 메모리는 고려되지 않습니다. 전체적인 그림에서 그래픽 카드용으로 예약된 메모리, 커널 사용, DOS 및 기타 선사 시대 시스템용으로 예약된 다양한 "구멍"(어쨌든 많지는 않음)을 고려해야 합니다.

전체 그림을 얻을 수 있는 유일한 방법은 커널이 보고하는 것입니다. 알 수 없는 중복과 알 수 없는 누락의 숫자를 추가하는 것은 좋은 산술 연습일 뿐입니다.

관련 정보