Rastreando o uso de memória "ausente" no Linux

10

Em um kernel do Arch 3.6.7 x86_64, estou tentando explicar o uso de memória do sistema. Quanto mais eu olho para ele, mais parece haver um buraco (na contabilidade da memória usada, um não buraco no o uso de).

Este é um sistema recém-inicializado. Com pouca execução além de systemd e sshd para simplificar

$ 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

A informação de memória mais detalhado que posso encontrar é esta a partir de 2007, que parece ter resultado na adição do campo Pss para o kernel geral respondendo por um processo, mas seu código python é para kernels mais antigos e, infelizmente, alguns dos arquivos / proc / k * desapareceram desde então. A documentação / proc / meminfo também é útil, mas também envelhece um pouco.

Então, uma demonstração do que estou vendo.

# 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 somarmos o usado:

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

Todos os Ativos * / Inativos * parecem ser contadores aplicados em algumas páginas (não todas), portanto, podem duplicar o que é contado em outros lugares.

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

O Commited_AS aqui parece acompanhar de perto a soma da memória compartilhada / privada do espaço do usuário, descontando os arquivos compartilhados de / proc / * / smaps. levar em conta o PSS também se alinha. (Por interesse, recebo um Commited_AS muito, muito maior em um debian de 32 bits 2.6.32-5-686)

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

A laje está alinhada com / proc / slabinfo

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

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

Tão ~ 63M curto. Parece-me que faltam alguns MBs no kernel e em todos os módulos carregados. A laje parece cobrir muito, então, se houver alguma falta, não tenho certeza se isso equivaleria a ~ 60Mb?

63 está bem próximo da figura Active + Inactive, mas isso não parece certo.

Então, alguém sabe a fórmula mágica? Caso contrário, se os números que estou vendo são os corretos, quais são as áreas cinzentas da alocação de memória nas quais posso mexer?

Parece linux comeu meu carneiro! Embora uma parcela menor do que normalmente acusado de =)

editar Commited_AS é uma estimativa do núcleo da quantidade de memória necessária para cobrir 99,9% do que foi comprometido, portanto, não é um número real alocado. O AnonPages + Mapped é um componente dele, de modo que deixa um buraco maior, cerca de 100 MB agora.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages e Mapped acompanham principalmente informações anon / mapeadas de / proc / [0-9] * / smaps wgen levando em consideração o PSS / Shared.

As áreas reservadas parecem se encaixar no pedaço retirado da memória total:

A freememória total é 16345032Kb
A memória total do sistema é 16777216Kb
'furo' do PCI - lspci -v 266520K = 16510696K
BIOS Reservado - dmesg 92793K = 16417903K

edit2 Notei que esse uso de memória extra não estava na máquina virtual em execução dentro da caixa original de onde /proc/meminfoera. Então comecei a bisbilhotar vendo o que havia de diferente entre os dois. Eventualmente, constatou que um aumento na memória física total disponível coincidia com o aumento na memória usada.

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

Isso resulta em ~ 8 Mb alocados para cada 1 GB de memória. Pode ser um mapa de memória no kernel ... mas pensei que só aumentaria à medida que a memória fosse alocada, em vez de ser configurada na inicialização.

Seria interessante ver se alguém tem acesso a máquinas bigmem se a tendência continuar?

Matt
fonte
psencontra-se por design. Não o use para contabilidade de memória.
21313 bahamat
2
Saúde, mas isso não está valendo ps. É uso geral em /proc/meminfo. A única contabilidade de processo foi através de smaps, que representam memória compartilhada e privada, mas isso foi apenas para comparar com os valores AnonPages / Mapped do meminfo.
Matt
linuxatemyram.com
Hannes Schneidermayer
daí a referência no meu post sobre linux realmente comendo a minha memória RAM =)
Matt

Respostas:

3

A "memória usada por um processo" não éum conceito claro nos sistemas operacionais modernos. O que pode ser medido é o tamanho do espaço de endereçamento do processo (SIZE) e o tamanho do conjunto de residentes (RSS, quantas páginas no espaço de endereçamento estão atualmente na memória). Parte do RSS é compartilhada (a maioria dos processos na memória compartilha uma cópia da glibc e, portanto, para várias outras bibliotecas compartilhadas; vários processos executando o mesmo executável o compartilham, os processos bifurcados compartilham dados somente leitura e, possivelmente, um pedaço de ainda não modificado ler / gravar dados com o pai). Por outro lado, a memória usada para o processo pelo kernel não é contabilizada, como tabelas de páginas, buffers do kernel e pilha do kernel. Na imagem geral, você deve considerar a memória reservada para a placa gráfica, o uso do kernel e diversos "buracos" reservados para o DOS e outros sistemas pré-históricos (isso não é muito,

A única maneira de obter uma visão geral é o que o kernel informa como tal. Adicionar números com sobreposições desconhecidas e saídas desconhecidas é um bom exercício de aritmética, nada mais.

vonbrand
fonte
1
'memória por processo' não é clara, mas não vejo por que isso deve afetar o rastreamento do uso geral? Para o kernel, o PageTables geral, o Slab, o KernelStack e outros contadores de memórias que não são de processo são relatados em / proc / meminfo e incluídos no que estou tentando explicar (o processo também parece estar lá). Além dos contadores gerais que eu estava examinando nos smaps por processo, para memória compartilhada / privada, não-mapeada, para ter uma idéia de onde a memória do processo poderia ser contabilizada em / proc / meminfo. Eu estou visando o conjunto de números VM adicionar até o físico, que claramente tem um buraco no.
Matt
1
Basicamente, psé incapaz de contabilizar corretamente a memória. Então não use. Quais psrelatórios seriam verdadeiros se esse processo fosse o único em execução no sistema (uma impossibilidade). Para saber mais sobre por que você não faça isso com psleia aqui: Uso de memória Entendimento sobre Linux
bahamat