Encontre algo que esteja ocupando muita memória e não seja visível em 'ps' ou similar

2

Eu tenho uma VM que está com problemas de memória. Uma das tarefas que gostaria de executar é a falha com erros de falta de memória.

No entanto, quando ele falha, o sistema ainda fica com memória insuficiente. Eu não tenho certeza se isso é apenas um processo que estou perdendo, ou um bug real (isso é no hyper-v, com as novas extensões do kernel que permitem o ballooning de memória para hosts linux, então pode muito bem ser um genuíno bug do kernel).

durr@sqlbox:~$ free -h
             total       used       free     shared    buffers     cached
Mem:          3.1G       2.6G       541M        88K       7.4M        39M
-/+ buffers/cache:       2.5G       588M
Swap:         1.0G       6.2M       1.0G

O Free me diz que não é apenas armazenado em cache, há realmente algo que parece estar vivo ocupando 2,6G de memória.

No entanto, observar a saída de PS classificada por tamanho virtual não é esclarecedor:

durr@sqlbox:~$ ps -e ax -o pid,vsz,comm | sort --numeric-sort --key=2
[ ... snip ... ]
  PID    VSZ COMMAND
   96      0 rcuob/23
   97      0 rcuob/24
   98      0 rcuob/25
   99      0 rcuob/26
 1124   4368 acpid
59863  10016 ps
 1031  15668 upstart-file-br
 1047  15820 getty
 1050  15820 getty
 1055  15820 getty
 1056  15820 getty
 1058  15820 getty
 1167  15820 getty
 1023  15920 upstart-socket-
 1076  19140 atd
 1099  19188 irqbalance
  428  19476 upstart-udev-br
59864  21860 sort
59267  22644 bash
59234  22664 bash
59280  22808 bash
 1075  23656 cron
59261  26928 screen
59279  27380 htop
59262  28472 screen
    1  33776 init
  749  39240 dbus-daemon
  816  43452 systemd-logind
  432  51348 systemd-udevd
 1090  61364 sshd
  871 255844 rsyslogd
59184 269028 sshd
59233 269028 sshd

Portanto, o maior consumidor de memória é sshd e está usando ..... 269K? Onde está toda a minha memória?

Olhando para /proc/meminfo mostra:

durr@sqlbox:~$ cat /proc/meminfo
MemTotal:        3266904 kB
MemFree:          554228 kB
Buffers:            7596 kB
Cached:            41104 kB
SwapCached:         3032 kB
Active:            32552 kB
Inactive:          34292 kB
Active(anon):      13224 kB
Inactive(anon):     5008 kB
Active(file):      19328 kB
Inactive(file):    29284 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       1044476 kB
SwapFree:        1038084 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         15656 kB
Mapped:             9196 kB
Shmem:                88 kB
Slab:              33488 kB
SReclaimable:      14532 kB
SUnreclaim:        18956 kB
KernelStack:        2352 kB
PageTables:         2748 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2677928 kB
Committed_AS:      56148 kB
VmallocTotal:   34359738367 kB
VmallocUsed:       34360 kB
VmallocChunk:   34359695660 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       44456 kB
DirectMap2M:     3491840 kB

Obviamente, parece que algo tem Vmalloc ed uma enorme quantidade de memória, mas não tenho certeza se isso é relevante.

    
por Fake Name 16.09.2014 / 07:04

1 resposta

5

Pode ser possível que seu programa tenha usado memória compartilhada e não tenha limpado isso.

Existem três variantes de memória compartilhada no linux:

1.) A memória compartilhada POSIX (aquela implementada pela glibc) é acessível por meio de arquivos no pseudo-sistema de arquivos tmpfs e geralmente é montada pelo sistema em locais como /dev/shm , /run , /run/shm ou %código%. A melhor maneira de descobrir com certeza é inserir /run/lock (mais portátil) ou mount | grep -E '^tmpfs' (melhor para o Linux) em um shell.

Observe que é possível para um processo chamar grep -E '^tmpfs' /proc/mounts em um arquivo unlink() 'ed na memória compartilhada, tornando o arquivo inacessível por meio do nome do arquivo (por exemplo, é necessário um identificador de arquivo previamente alocado para continuar acessando-o). No entanto, mmap() ed arquivos são geralmente excluídos ao sair de todos os processos que tinham unlink() 'ed - talvez se o seu programa terminar, ainda há outro processo ainda segurando um identificador para ele.

2.) Memória compartilhada SysV IPC, que não é visível através do pseudo-sistema de arquivos open() , mas via tmpfs , syscalls do Linux (somente se você for um hacker), seu wrapper libc ou, mais recentemente via /proc/sysvipc/shm . Você precisa encontrar um ID de processo correspondente em qualquer uma dessas listas e, em seguida, inspecionar esse processo ainda mais.

3.) Memória compartilhada mapeada anônima, em cujo caso a memória não é suportada por nenhum arquivo, mas sim a memória é inicialmente compartilhada entre um processo e todos os seus filhos. AFAIK essa memória compartilhada mapeada anônima é liberada quando o processo que ipcs -m -p -[tclu] 'ed it mmap() s. Então, caso o seu programa tenha terminado e todos os seus processos filhos também tenham funcionado, eles não devem mais ocupar a memória.

    
por 16.09.2014 / 18:20