Entenda o que está acontecendo no Linux com ps, top e free

0

Estou executando meu programa java em uma máquina de 24 threads de 12 núcleos. Eles têm vários processos que estão sendo executados simultaneamente. Parece que eu realizei muitos processos para que todas as tarefas tornassem a máquina muito lenta.

Aqui está a informação principal

Tasks: 556 total,   2 running, 554 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.1%us,  0.4%sy,  0.0%ni, 63.2%id, 36.3%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  16295248k total, 16169560k used,   125688k free,     3300k buffers
Swap: 18530296k total, 10867972k used,  7662324k free,    46188k cached

Parece que meus processos são orientados para o consumo de memória, de modo que quase toda a memória foi usada por eles. Nas principais informações, o que eu não entendo é por que apenas duas tarefas estão sendo executadas, em vez de 23 (eu despachei 23 processos).

free -g
             total       used       free     shared    buffers     cached
Mem:            15         15          0          0          0          0
-/+ buffers/cache:         15          0
Swap:           17         10          7

Parece que toda a memória foi usada e foi a troca que fez a máquina diminuir a velocidade.

ps -e -o pid,%cpu,%mem,vsz,rss,comm= --sort=vsz
29707  5.6  4.2 6268732 685660 java
29712  5.2  3.9 6268732 647352 java
...
30269  3.2  4.3 6268732 704676 java
30334  4.8  4.2 6268732 689544 java

Existem 23 desses processos java. Somando todos os% cpu, está muito próximo de 100%. Mas as principais informações indicam que a CPU não está ocupada.

Cpu(s):  0.1%us,  0.4%sy,  0.0%ni, 63.2%id, 36.3%wa,  0.0%hi,  0.0%si,  0.0%st

Eu pesquisei o tamanho de vsz e rss mas não descobri. Eu suponho que a unidade esteja no byte do quilo. Observando o vsz então os processos java estão usando 6268732kb * 23 = 144,180,836 = ~ 144gb, o que parece ser impossível colocar na RAM porque é muito mais que minha RAM (16gb), então apenas 700000kb * 23 = ~ 16gb foram colocados na memória (com a informação rss, que é a parte do armazenamento de dados na RAM). Por causa do frequente troca e troca de contexto, o sistema ficava lento.

Eu não sei se minha conclusão está correta ou não. Por favor, me dê alguns conselhos e como posso corrigir o problema.

Adicione mais detalhes:

vmstat -a -S M
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 2 29  16792    124   2105  13152    0    0    29    23    2    0  1  0 95  4  0

Eu não sei como devo interpretar os dados do vmstat. É um pouco estranho porque swpd: a quantidade de memória virtual usada parece alta enquanto si e so são 0.

    
por Marcus Thornton 18.12.2013 / 09:26

2 respostas

0

O seu sistema está claramente ausente da RAM.

  • adicione mais RAM (esperando que você não precise adicionar até 128 GB)
  • limita o número de instâncias da JVM, pois cada uma utiliza 6 GB de memória virtual.
  • ajuste-os para usar menos memória, estas são JVMs de 64 bits, dê uma olhada no sinalizador -Xmx.

Não há problema de CPU.

    
por 18.12.2013 / 10:05
0

Sua conclusão está de fato correta. Os tamanhos de memória estão em KB, ambos vsz e rss, como você pode verificar a si mesmo olhando a página Man para ps, na seção ESPECIFICADORES DE FORMATO PADRÃO .

Há também outra verificação que você pode realizar: o rss (tamanho do conjunto de residentes, isto é, a memória não trocada usada por cada processo) é de aproximadamente 700 MB por processo. Se você tem 23 processos desse tipo, isso é bom para os 15 GB de memória usada (não para swap).

Além disso, o tamanho total de sua memória física + troca é muito menor do que o requerido pela execução simultânea dessas 23 tarefas, 16 GB vs. 144 GB. Portanto, parece que nem mesmo um único processo recebe a quantidade necessária de memória neste momento.

Então, quais são suas opções? Basta executar dois processos de cada vez, já que seu tamanho é tal que você pode mantê-los completamente em sua memória, sem trocar. Quando terminarem, carregue mais dois. Isso pode ser facilmente realizado com um script bash, com o comando wait :

   my_job < file1.txt &
   my_job < file2.txt &
   wait 1 2
   my_job < file3.txt
   my_job < file4.txt
   wait 3 4....

Isso também lhe deixará algum espaço na memória para manter o / tmp, / run e assim por diante, o que significa que a capacidade do seu sistema de executar interativamente será pouco afetada.

A segunda opção (talvez a primeira), seria perguntar a si mesmo como você acabou com um código java de 7GB ... mas essa é uma pergunta para o StackOverflow

Editar:

Estou respondendo aqui ao comentário de Marcus Thornton:

If I can fix the memory issue, ..., is it good to dispatch all the tasks at one time?

Sim e não. Se você corrigir o problema de memória, certamente poderá executar mais de dois trabalhos simultaneamente. Mas você consegue executar 23? Eu acho que você está superestimando a utilidade do Multi-threading . O multiencadeamento é um processador único, com dois contextos de execução, o que permite o uso paralelo de diferentes unidades funcionais no mesmo processador. Mas se as tarefas são similares , como elas são no seu caso, elas provavelmente usarão as mesmas unidades funcionais, assim elas serão enfileiradas como se não houvesse multi-threading . Multi-threading não é a mesma coisa que ter processadores independentes, e permite ganhos de velocidade marginais, na melhor das hipóteses.

BTW, como você pode usar o cpus? Você disse processadores, não cpu. O seguinte comando

  /bin/cat /proc/cpuinfo | /bin/egrep 'processor|model name|cache size|core|sibling|physical'

irá ajudá-lo.

    
por 18.12.2013 / 10:08