Parecido com o artigo sobre consumo de CPU, hoje escreverei sobre consumo de memória, contemplando parte teórica e prática.
Basic Concepts
Quando observamos algumas informações sobre memória, é importante ter noção que:
- Total = Memória total instalada e reconhecida pelo S.O
- Used = Memória total usada no S.O, incluindo Buffer e Cache
- Free = Reserva de memória livre disponível para uso
- Buffers = espaço utilizado pelo Kernel, em caráter temporário, para otimizar operações internas
- Cache = memória usada como cache para leitura de arquivos lidos do disco, melhorando assim a performance de I/O. Uma maneira de ver essa diferença foi demonstrada NESTE artigo do nosso blog.
Temos essas informações dispostas no man abaixo e no Oracle Note “Oracle Linux: System Memory Utilization (Doc ID 1514705.1)“:
How to Calculate Memory Usage
Uma vez com os conceitos teóricos, podemos evoluir.
Quando observamos o comando free, podemos ter a tendência de considerar a coluna free como o valor de memória livre disponível no servidor (e que em muitos casos, está muito baixa):
[oracle@oel7 ~]$ free -m
total used free shared buff/cache available
Mem: 15772 1152 12360 1147 2259 13307
Swap: 1231 0 1231
O grande erro aqui é não considerar os valores de Buffer e Cache, pois o Linux reutiliza essas áreas de memória durante suas operações. Ou seja, o cálculo correto deveria ser: Free + Buffer + Cache.
Top 10 users and processes are consuming memory on system
Caso seja identificado que há algum problema na camada de memória do servidor, é possível verificar através do comando abaixo os Top 10 Users em porcentagem de consumo. No exemplo temos 32.70% do usuário oracle e 12.40% do grid.
# ps -eo user,pcpu,pmem | tail -n +2 | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{printf("NPROC\tUSER\tCPU\tMEM\n"); for (user in cpu) printf("%d\t%s\t%.2f\t%.2f\n",num[user], user, cpu[user], mem[user]) }'
[oracle@oel7 ~]$ ps -eo user,pcpu,pmem | tail -n +2 | awk '{num[$1]++; cpu[$1] += $2; mem[$1] += $3} END{printf("NPROC\tUSER\tCPU\tMEM\n"); for (user in cpu) printf("%d\t%s\t%.2f\t%.2f\n",num[user], user, cpu[user], mem[user]) }'
NPROC USER CPU MEM
32 grid 4.20 12.40
1 rpc 0.00 0.00
83 oracle 2.00 32.70
1 colord 0.00 0.00
1 rtkit 0.00 0.00
1 polkitd 0.00 0.00
1 dbus 0.00 0.00
1 nobody 0.00 0.00
31 gdm 0.20 1.90
1 libstor+ 0.00 0.00
2 avahi 0.00 0.00
2 postfix 0.00 0.00
177 root 0.00 0.40
[oracle@oel7 ~]$
Para identificar os processos que mais consomem memória, podemos usar:
ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS| tail -10
[oracle@oel7 ~]$ ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS| tail -10
114656 4347 oracle ora_cjq0_cortex
115364 3065 grid /grid/19.3.0/product/bin/ohasd.bin reboot
134704 3596 grid /grid/19.3.0/product/bin/oraagent.bin
138544 23266 oracle ora_m003_cortex
151368 4107 oracle ora_mman_cortex
191948 3162 gdm /usr/bin/gnome-shell
223320 4160 oracle ora_mmon_cortex
250180 4180 oracle ora_m000_cortex
285352 4694 oracle ora_m005_cortex
306536 4579 oracle ora_m002_cortex
[oracle@oel7 ~]$
Definição de cada coluna, conforme Oracle Note “Oracle Linux: How to Calculate Memory Usage (Doc ID 1630754.1)“: First column is RSS, second one is PID, the third one is USER and fourth is Command Executed – to sum-up first column only and give total in KB allocation, below command can be used:
ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS| awk '{total += $1} END{print"sum="total}'
[oracle@oel7 ~]$ ps -e -orss,pid=,user=,args=, | sort -b -k1,1n | pr -TW$COLUMNS| awk '{total += $1} END{print"sum="total}'
sum=10009904
Swap Space Usage
A depender das operações que executam no servidor, pode ocorrer da área de memória não ser suficiente (ou seja, naquela dinâmica de carregar dados de disco para memória, e memória para disco, não conseguir dar vazão). Para estas ocasiões, o Linux utiliza da área de Swap, que em caráter temporário faz a função de “memória”. Quando esses eventos ocorrem de forma pontual, não é um problema, mas caso percebamos que a situação fica prolongada, isso acarreta sérios problemas de performance.
A manifestação dessas ocorrências podem ser vistas a partir da ferraments vmstat, nas colunas SI e SO:
Segundo o Oracle Note “Oracle Linux: How to Check Whether a System is Under Memory Pressure (Doc ID 1502301.1)“, os eventos de SO (Memória para Disco) podem ser normais e esperados: When an application requests memory from the operating system, it does not specify swap or physical memory, it just requests memory, the operating system manages the allocation of memory and use of swap.
Para identificar eventos anômalos: as colunas SI e SO precisam estar com valores acima de 0 de maneira prolongada. No exemplo abaixo, temos um ambiente sem problemas de memória:
[oracle@oel7 ~]$ vmstat 1 10 -S m
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 5664 9 1815 0 0 41 0 697 556 13 6 64 17 0
0 0 0 5640 9 1823 0 0 173 0 2768 2070 8 7 83 2 0
2 0 0 5584 9 1826 0 0 0 0 3192 2032 4 8 87 1 0
0 0 0 5553 9 1848 0 0 4 0 5109 6138 10 6 81 4 0
0 0 0 5551 9 1848 0 0 2257 0 1692 1812 1 1 94 4 0
0 0 0 5547 9 1852 0 0 228 0 1095 1251 0 1 98 1 0
0 0 0 5542 9 1852 0 0 0 0 1208 1367 1 1 98 0 0
0 0 0 5542 9 1852 0 0 156 0 970 1236 0 0 99 0 0
0 0 0 5541 9 1852 0 0 0 0 935 1317 0 0 99 0 0
1 1 0 5541 9 1852 0 0 0 0 1262 1330 1 1 98 0 0
[oracle@oel7 ~]$
Stressando o ambiente:
[root@oel7 ~]# stress --cpu 1 --vm 12 --vm-bytes 900M --timeout 60s
[oracle@oel7 ~]$ vmstat 1 10 -S m
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
5 42 1267 4627 2 1370 1 0 1305 6 689 460 9 15 36 39 0
2 44 1274 4625 2 1374 6 0 6352 92 3107 2346 1 3 0 96 0
1 37 1286 4636 2 1370 13 0 12796 131 4525 2608 0 3 0 96 0
0 34 1291 4647 2 1366 6 0 6544 97 4748 3118 0 2 0 97 0
1 34 1259 5553 2 1374 4 0 4711 102 4223 3440 1 6 0 93 0
0 32 1264 5554 2 1372 5 0 5112 139 3923 3235 1 2 0 97 0
0 38 1276 5564 2 1369 12 0 11776 88 3374 2787 0 3 0 97 0
0 35 1287 5577 2 1361 12 0 12360 111 4083 3095 0 3 0 97 0
3 34 1291 5582 2 1358 5 0 5485 176 4090 3396 0 2 0 98 0
0 36 1291 5589 2 1356 0 0 944 271 4285 3923 1 4 0 96 0
[oracle@oel7 ~]$
Vemos que a coluna SI ficou com números acima de 0, além do Load da máquina também ter sido comprometido (o que é esperado quando isso ocorre).
Em suma, para diagnosticar problemas comuns de memória em servidores, é aconselhado validar se o mesmo está lidando com uso constante de Swap, o que pode significar que a memória física alocada está insuficiente para a carga executada, ou pode existir algum processo que está fazendo consumo demasiado de memória, e deve ser revisto. Referência: