Rintracciare l'utilizzo della memoria "mancante" in Linux


10

Su un kernel Arch 3.6.7 x86_64 sto cercando di spiegare l'utilizzo della memoria del sistema, che più lo guardo, più sembra esserci un buco (nella contabilità della memoria usata, un non buco in l'uso di).

Questo è un sistema appena avviato. Con poca esecuzione diversa da systemd e sshd per mantenerlo semplice

$ 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

Le informazioni di memoria più dettagliate che riesco a trovare sono queste dal 2007, che sembrano aver portato all'aggiunta del campo Pss alla contabilità generale del kernel per un processo, ma il loro codice Python è per kernel più vecchi e sfortunatamente alcuni dei file / proc / k * sono scomparsi da allora. Anche la documentazione / proc / meminfo è utile, ma invecchia anche un po '.

Quindi, una dimostrazione di ciò che sto vedendo.

# 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

Se sommiamo il usato:

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

Tutti gli Attivi * / Inattivi * sembrano essere contatori applicati su alcune pagine (non tutte), quindi potrebbero duplicare ciò che viene contato altrove.

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

Commited_AS qui sembra seguire da vicino la somma della memoria privata / condivisa dello spazio utente che attualizza i file condivisi da / proc / * / smaps. prendendo in considerazione anche il PSS . (Per interesse ottengo un Commited_AS molto, molto più grande su un debian a 32 bit 2.6.32-5-686)

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

La lastra è in linea con / proc / slabinfo

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

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

Quindi ~ 63M in breve. Mi sembra che al kernel e a tutti i moduli caricati manchino alcuni MB. La lastra sembra coprire molto però, quindi se manca qualcosa non sono sicuro che equivarrebbe a ~ 60 Mb?

63 è un po 'vicino alla figura Attivo + Inattivo ma non sembra giusto.

Qualcuno conosce la formula magica ?? Altrimenti, se la figura che sto guardando è quella giusta, quali sono le aree grigie nell'allocazione di memoria che posso colpire?

Sembra che Linux abbia mangiato il mio ariete! Anche se una porzione più piccola di quella normalmente accusata di =)

modifica Commited_AS è una stima del kernel di quanta memoria avrebbe bisogno per coprire il 99,9% di ciò che ha commesso, quindi non è un numero assegnato reale. AnonPages + Mapped ne è un componente, quindi lascia un buco più grande, circa 100 MB ora.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages e Mapped tracciano principalmente con anon / mapped info da / proc / [0-9] * / smaps wgen prendendo in considerazione PSS / Shared.

Le aree riservate sembrano adattarsi perfettamente al blocco rimosso dalla memoria totale:

La freememoria totale è 16345032Kb
La memoria totale del sistema è 16777216Kb
PCI 'hole' - lspci -v 266520K = 16510696K
Bios riservato - dmesg 92793K = 16417903K

edit2 Ho notato che questo utilizzo di memoria extra non era in esecuzione nella VM all'interno della scatola originale /proc/meminfoda cui proveniva. Così ho iniziato a frugare nel vedere cosa era diverso tra i due. Alla fine si è scoperto che un aumento della memoria fisica totale disponibile coincideva con l'aumento della memoria utilizzata.

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

Questo risulta essere allocato a ~ 8 Mb per ogni 1 GB di memoria. Potrebbe essere una mappa di memoria nel kernel ... ma ho pensato che sarebbe cresciuto solo quando la memoria è allocata piuttosto che essere impostata all'avvio.

Sarebbe interessante vedere se qualcuno ha accesso a macchine bigmem se la tendenza continua?


pssi trova in base al design. Non utilizzarlo per la contabilità della memoria.
Bahamat,

2
evviva, ma questo non è un riscontro ps. È un utilizzo generale in /proc/meminfo. L'unico processo di contabilità è stato tramite smaps che tiene conto della memoria condivisa e privata, ma era solo per confrontare con i valori AnonPages / Mapped di meminfo.
Matt,


quindi il riferimento nel mio post su Linux sta effettivamente mangiando il mio ram =)
Matt

Risposte:


3

La "memoria utilizzata da un processo" non lo èun concetto chiaro nei moderni sistemi operativi. Ciò che può essere misurato è la dimensione dello spazio degli indirizzi del processo (SIZE) e la dimensione del set residente (RSS, quante pagine dello spazio degli indirizzi sono attualmente in memoria). Parte dell'RSS è condivisa (la maggior parte dei processi in memoria condivide una copia di glibc, quindi per altre librerie condivise assortite; diversi processi che eseguono lo stesso eseguibile lo condividono, i processi biforcati condividono dati di sola lettura e possibilmente un pezzo di non ancora modificato lettura / scrittura dei dati con il genitore). D'altra parte, la memoria utilizzata per il processo dal kernel non viene presa in considerazione, come tabelle di pagine, buffer del kernel e stack del kernel. Nell'immagine generale devi tenere conto della memoria riservata per la scheda grafica, dell'uso del kernel e dei "buchi" assortiti riservati per DOS e altri sistemi preistorici (non è molto,

L'unico modo per ottenere un quadro generale è ciò che il kernel riporta come tale. Sommare numeri con sovrapposizioni sconosciute e mancanze sconosciute è un bel esercizio di aritmetica, niente di più.


1
'memoria per processo' non è chiara ma non riesco a capire perché ciò dovrebbe influire sul monitoraggio dell'utilizzo complessivo? Per il kernel, PageTables, Slab, KernelStack e altri contatori di mem non di processo complessivi sono riportati in / proc / meminfo e inclusi in ciò che sto cercando di rendere conto (sembra che anche la mem di processo sia presente). Oltre ai contatori generali, stavo esaminando gli smaps per processo per memoria anon / mappata, condivisa / privata per avere un'idea di dove la memoria di processo potesse essere spiegata in / proc / meminfo. Sto mirando a quale serie di numeri di VM si sommano al fisico, in cui chiaramente ho un buco.
Matt

1
Fondamentalmente psnon è in grado di tenere correttamente conto della memoria. Quindi non usarlo. Quali psrapporti sarebbero veri solo se quel processo fosse l'unico in esecuzione sul sistema (un'impossibilità). Per ulteriori informazioni sul perché non lo fai con psleggi qui: Comprensione
dell'utilizzo della
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.