Como detectar um vazamento de memória?

16

Parece que tenho um vazamento de memória maior no meu sistema atual do ubuntu

Após relatar erros de memória estranhos do Eclipse ( /ubuntu/148998/eclipse-constant-different-out-of-memory-errors ), comecei a receber mensagens de erro 'Memória insuficiente' no meu console hoje - enquanto executando tarefas simples como digitar sudo -s- ou até mesmo -free -m

Digitar 'free -m' repetidamente me mostrou como minha RAM aumenta rapidamente de 700M para 900M, crescendo até o tamanho de 2000M em alguns segundos (depois de liberar memória com echo 3 > /proc/sys/vm/drop_caches)

Eclipse não é a causa, eu finalizei completamente o processo e o carneiro ainda estava subindo. Existe alguma maneira de detectar de onde vem o vazamento? Não consigo mais atualizar meu sistema, pois apt-get updatefalha (provavelmente porque está com falta de memória)

Usando Ubuntu 11.10

Katai
fonte
Estou muito feliz, não sou louca. Eu tive o mesmo problema desde a atualização para a 13.10, mas lembro-me de tê-lo com a 11.10. A pergunta é: você está usando o CrashPlan? Eu pareço tê-lo reduzido a isso, eu simplesmente não sei como consertá-lo. Eu tentei os ajustes de memória, mas não está funcionando. Espero que isso lhe dê algumas pistas #
semi-newbie
Não faz sentido forçar o kernel a eliminar caches. Eles serão liberados e seu espaço recuperado de qualquer maneira assim que mais memória física for necessária. A descarga forçada deles provavelmente prejudica o desempenho geral, pois os objetos não armazenados em cache precisam ser recuperados de um armazenamento secundário muito mais lento. A memória principal livre não é de modo algum uma coisa boa. É um sinal de mau gerenciamento de cache ou uso muito leve.
David Foerster

Respostas:

9

O memprof é uma ferramenta para criar perfil de uso da memória e encontrar vazamentos de memória. Ele pode gerar um perfil de quanta memória foi alocada por cada função no seu programa. Além disso, ele pode verificar a memória e encontrar os blocos que você alocou, mas não são mais mencionados em nenhum lugar.

O memprof trabalha pré-carregando uma biblioteca para substituir as funções de alocação de memória da biblioteca C e não exige que você recompile seu programa.

memprof

Fonte: Manual do Ubuntu

Mitch
fonte
11

Primeiro, verifique se há uma pasta temporária disponível com espaço livre suficiente. Os comandos a seguir criam despejos que podem ter vários GBs de tamanho.

Você pode criar uma nova pasta tmp usando o seguinte comando. Você pode querer mudar /tmppara um sistema de arquivos diferente, com espaço suficiente

TMPDIR=$(mktemp -d -t -p /tmp)

Etapas para encontrar vazamento de memória

  1. Descubra o PID do processo que está causando o vazamento de memória (você também pode usar, por exemplo, htopse disponível) e armazene-o em uma variável chamadapid

    ps -aux
    
  2. Dado que o PID está disponível na variável pid, você pode capturar o consumo de memória usando /proc/$pid/smapse salvando em algum arquivo como beforeMemInc.txt.

    cat /proc/$pid/smaps > $TMPDIR/beforeMemInc.txt
    
  3. Aguarde algum tempo para aumentar o consumo de memória.
  4. Capture /proc/$pid/smapsnovamente e salve-o comoafterMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/afterMemInc.txt
    
  5. Encontre a diferença entre o primeiro smapse o segundo smaps, por exemplo, com

    diff -u $TMPDIR/beforeMemInc.txt $TMPDIR/afterMemInc.txt
    
  6. Anote o intervalo de endereços em que a memória aumentou, por exemplo:

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
    
  7. Use o GDB para despejar memória no processo em execução ou obter o coredump usando

    gcore -o $TMPDIR/process $PID
    
  8. Eu usei o gdb no processo em execução para despejar a memória em algum arquivo.

    cd $TMPDIR
    gdb -p $pid
    dump memory memory.dump 0x2b3289290000 0x2b3289343000
    
  9. Agora, use o stringscomando ou hexdump -Cpara imprimir omemory.dump

    strings memory.dump
    

    A partir disso, você obtém informações legíveis que ajudam a localizar essas strings no seu código-fonte.

  10. Analise sua fonte para encontrar o vazamento.
Jagannath Pattar
fonte
Estou em um contêiner do Docker, recebendo um erro de permissão negada ao executar cat /proc/2882/smaps > /tmp/before.txtna etapa 2. O que fiz de errado?
Devy
8

O truque drop_cache não liberará memória, redefinirá o cache. Usa o comando ps se você deseja identificar quais processos usam mais memória.

Por exemplo, para monitorar a lista dos 15 principais usuários de memória residente.

$ watch "ps --sort -rss -eo pid,pmem,rss,vsz,comm | head -16"
  PID %MEM   RSS    VSZ COMMAND
 2590 13.4 136892 825000 firefox
 1743 10.7 109020 300780 Xorg
 2067  8.5 86764 1118140 unity-2d-shell
 3307  4.1 42560 627780 unity-2d-spread
 2068  2.9 29904 617644 unity-2d-panel
 2092  2.5 25524 1291204 nautilus
 2457  1.9 20292 530276 gnome-terminal
 2351  1.9 20016 821488 unity-scope-vid
 2161  1.9 19476 531968 unity-panel-ser
 2034  1.7 18256 759716 gnome-settings-
 2074  1.5 16176 518016 nm-applet
 2273  1.5 15452 580416 unity-lens-vide
 2051  1.4 15112 524260 metacity
 2395  1.2 12836 407336 update-notifi

Você também pode verificar a reserva de memória compartilhada, mas só saberá quem é o proprietário dos segmentos.

Alocação de Pmap:

$ ls -l /run/shm
total 272
-r-------- 1 ed      ed      67108904 Nov 29 18:17 pulse-shm-1884617860
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-2352897759
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3444873503
-r-------- 1 ed      ed      67108904 Nov 29 18:12 pulse-shm-3485341848
-r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-535843976
-r-------- 1 ed      ed      67108904 Nov 29 19:12 pulse-shm-789046959
-r-------- 1 ed      ed      67108904 Nov 29 18:38 pulse-shm-863909656

$ df /run/shm 
Filesystem     1K-blocks  Used Available Use% Mounted on
none              509332   272    509060   1% /run/shm

observe que as alocações reservadas são muito mais altas que as páginas alocadas reais (df 'used')

Alocações do sistema V:

$ ipcs -m 

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 294912     ed         700        122880     2          dest         
0x00000000 327681     ed         700        4823040    2          dest         
0x00000000 491522     ed         600        393216     2          dest         
0x00000000 589827     ed         700        4578120    2          dest         
0x00000000 425988     ed         700        27852      2          dest         
0x00000000 458757     ed         600        393216     2          dest         

Editar : é necessário passar --sort -rsspara psobter os processos com mais uso de memória; caso contrário, a lista de processos é classificada aumentando numérica e fornece aos processos com menos uso de memória.

Emmanuel
fonte
5

Eu tenho uma máquina mais antiga que eu uso que cospe constantemente mensagens de vazamento de memória:

root@:~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1523        374        131         32        588
-/+ buffers/cache:        902        995
Swap:         1942        480       1462

Meu script:

sync; sudo echo 3 > /proc/sys/vm/drop_caches

Nomeado cache.sh

root@~# ./cache.sh
root@~# free -m
             total       used       free     shared    buffers     cached
Mem:          1898       1106        791        126          1        207
-/+ buffers/cache:        897       1000
Swap:         1942        480       1462

Você pode ver que eu tinha 374 MB, executei o sync; sudo echo 3 > /proc/sys/vm/drop_cachese ganhei 417 MB de volta. Pode cron-se executar a cada 5 minutos ou apenas abrir um terminal e executá-lo quando houver desempenho lento. Sim, preciso adicionar memória à máquina ...

Warpig
fonte
Formatação parece ser um problema, não tenho certeza como corrigir
Warpig
11
Use o link de edição abaixo da sua postagem. Há uma barra de ferramentas de formatação e um ponto de interrogação laranja acima da área de texto, vinculado à ajuda de formatação do Markdown .
David Foerster
Por favor, dê uma olhada no meu comentário recente sobre a questão . Estou convencido de que a idéia de liberar memória principal liberando e eliminando caches é equivocada e sei que não estou sozinha com essa conclusão.
David Foerster
Muito obrigado, David ... Eu concordo totalmente que o cache de descarga / descarte está errado ... Mas algo está sendo interrompido e está congelando / travando a máquina ... Apenas confuso quanto ao que é, pensando que é um problema do Firefox. ..
Warpig
3

O memstat também é uma boa ferramenta que mostra a quantidade de memória usada por cada bloco, bem como a quantidade de memória usada pelas bibliotecas carregadas. Não é a melhor ferramenta, mas vale a pena usar para reunir detalhes e estatísticas.

memstat -w -p pid é um bom comando para usar.

Chef Faraó
fonte
11
ligação é interrompida, eu acho que este é bom
vladkras
1

Eu tive um problema semelhante, mas com uma solução muito estranha.

Por alguma razão desconhecida, eu tinha um servidor de e-mail no meu laptop configurado e em execução. Não sei por que o tinha ... No entanto, desliguei o serviço e percebi que esse software no meu laptop estava sob ataque de ddos. Depois disso tudo foi normal.

Mario Kamenjak
fonte