Pergunta

Estou perfilando meu servidor torcido. Ele usa muito mais memória do que eu esperava. Seu uso de memória cresce com o tempo.

 ps -o pid,rss,vsz,sz,size,command
  PID   RSS    VSZ    SZ    SZ COMMAND
 7697 70856 102176 25544 88320 twistd -y broadcast.tac

Como você pode ver, custa 102176 KBS, a saber, 99.78125 MBS. E eu uso o Guppy de um bueiro torcido para assistir ao perfil de uso da memória.

>>> hp.heap()
Partition of a set of 120537 objects. Total size = 10096636 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  61145  51  5309736  53   5309736  53 str
     1  27139  23  1031596  10   6341332  63 tuple
     2   2138   2   541328   5   6882660  68 dict (no owner)
     3   7190   6   488920   5   7371580  73 types.CodeType
     4    325   0   436264   4   7807844  77 dict of module
     5   7272   6   407232   4   8215076  81 function
     6    574   0   305776   3   8520852  84 dict of class
     7    605   1   263432   3   8784284  87 type
     8    602   0   237200   2   9021484  89 dict of type
     9    303   0   157560   2   9179044  91 dict of zope.interface.interface.Method
<384 more rows. Type e.g. '_.more' to view.>

Hum ... parece que há algo errado. Guppy mostra que o uso total da memória é 10096636 bytes, a saber, 9859.996 KBS ou 9.628 MBS.

Essa é uma enorme diferença. O que há de errado esse resultado estranho? O que estou fazendo errado?

Atualizar:Eu escrevi um script de monitor ontem à noite. Ele registra o uso da memória e o número de usuários on-line. É um servidor de rádio, para que você possa ver que há rádios e ouvintes totais. Aqui está a figura que eu gerei por matplotlib.alt text

Algo é estranho. Às vezes, o uso de memória impresso por PS é muito baixo, assim

2010-01-15 00:46:05,139 INFO 4 4 17904 36732 9183 25944
2010-01-15 00:47:03,967 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:48:04,373 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:49:04,379 INFO 4 4 17916 36732 9183 25944
2010-01-15 00:50:02,989 INFO 4 4 3700 5256 1314 2260

Qual é o motivo do valor super baixo do uso da memória? E além do mais, mesmo não há rádios on-line, nem ouvintes, o uso da memória ainda é alto.

Foi útil?

Solução

Possivelmente devido à troca/reserva de memória, com base na definição do PS:

RSS: resident set size, the non-swapped physical memory
     that a task has used (in kiloBytes).

VSZ: virtual memory usage of entire process.
     vm_lib + vm_exe + vm_data + vm_stack

Pode ser um pouco confuso, 4 métricas de tamanho diferentes podem ser vistas com:

# ps -eo pid,vsz,rss,sz,size,cmd|egrep python

PID    VSZ   RSS   SZ    SZ    CMD
23801  4920  2896  1230  1100  python

O tamanho virtual inclui memória reservada pelo processo e não usada, o tamanho de todas as bibliotecas compartilhadas que foram carregadas, páginas que são trocadas e blocos que já foram libertados pelo seu processo, para que possa ser muito maior do que o tamanho de todos os objetos vivos em Python.

Algumas ferramentas adicionais para investigar o desempenho da memória:

Bom guia sobre o rastreamento de vazamentos de memória em Python usando PDB e ObjGraph:

http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks

Outras dicas

Como apontado acima do tamanho do RSS, é o que você está mais interessado aqui. O tamanho "virtual" inclui bibliotecas mapeadas, que você provavelmente não deseja contar.

Já faz um tempo desde que eu usei muito, mas tenho certeza de que as estatísticas que as impressões não incluem sobre a ponta adicionada pelo próprio Heapy. Essa sobrecarga pode ser bastante significativa (eu vi um processo RSS de 100 MB crescer mais uma dúzia ou mais MB, veja http://www.pkgcore.org/trac/pkgcore/doc/dev-notes/heapy.rst ).

Mas, no seu caso, suspeito que o problema é que você esteja usando uma biblioteca C que vaza ou usa a memória de uma maneira que Heay não rastreia. Heay está ciente da memória usada diretamente pelos objetos Python, mas se esses objetos embrulham objetos C que são alocados separadamente, normalmente não estiver ciente dessa memória. Você poderá adicionar suporte pesado às suas ligações (mas se você não controlar as ligações que usa, obviamente é um aborrecimento, e mesmo se você controlar as ligações, talvez não seja capaz de fazer isso, dependendo do que está envolvendo ).

Se houver vazamentos no nível C Heapy, também perderá o controle dessa memória (o tamanho do RSS aumentará, mas o tamanho relatado de Heapy permanecerá o mesmo). Valgrind é provavelmente sua melhor aposta para rastreá -los, assim como em outros aplicativos C.

Finalmente: A fragmentação da memória geralmente faz com que o uso da sua memória (como visto no topo) suba, mas não para baixo (muito). Geralmente, isso não é um grande problema com os daemons, pois o processo reutiliza essa memória, ele simplesmente não é lançado de volta ao sistema operacional; portanto, os valores no topo não retornam. Se o uso da memória (como visto por cima) subir mais ou menos linearmente com o número de usuários (conexões), não volta, mas também não continua crescendo para sempre até que você atinja um novo número máximo de usuários, a fragmentação provavelmente será culpar.

Esta não é uma resposta completa, mas no seu bueiro, eu também sugiro executar manualmente gc.collect () antes de procurar com PS ou top. Guppy mostrará a pilha alocada, mas não faz nada para liberar objetos proativamente que não são mais alocados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top