Como medir o uso real de memória de um aplicativo ou processo?


712

Esta questão é abordada aqui em grandes detalhes.

Como você mede o uso de memória de um aplicativo ou processo no Linux?

No artigo do blog Noções básicas sobre o uso da memória no Linux , psnão é uma ferramenta precisa a ser usada para esse objetivo.

Por que psestá "errado"

Dependendo de como você olha para ele, psnão está relatando o uso real da memória dos processos. O que realmente está fazendo é mostrar quanta memória real cada processo consumiria se fosse o único processo em execução . Obviamente, uma máquina Linux típica possui várias dezenas de processos em execução a qualquer momento, o que significa que os números VSZ e RSS relatados por psestão quase definitivamente errados .


6
Essa pergunta provavelmente pertence ao serverfault.com hoje em dia, embora esteja dizendo que é "muito antiga para migrar". Na verdade, não quero fechá- lo ...
thomasrutter


2
Na verdade ps, nem mostra isso - mostra números de memória virtual e residente, onde virtual é a quantidade máxima de memória que o processo poderia teoricamente usá-lo, pois era o único processo (nunca), usado em todas as páginas alocadas (nunca acontece) e não mapeou ou remove o mapeamento de nenhuma página (improvável). Enquanto residente mostra quanta memória virtual está mapeada para física no momento. Normalmente, virt > usage > resporém, em um sistema de 64 bits virt ~= res*10, é uma gama muito ampla.
Dima Tisnek

5
O trecho do artigo vinculado é totalmente sem sentido. O RSS é a memória física realmente usada e o VSZ pode ou não ser convertido em uso de memória física, mesmo que o processo tenha sido o único em execução.
David Schwartz

Respostas:


356

Com psou ferramentas semelhantes, você obterá apenas a quantidade de páginas de memória alocada por esse processo. Este número está correto, mas:

  • não reflete a quantidade real de memória usada pelo aplicativo, apenas a quantidade de memória reservada para ele

  • pode ser enganoso se as páginas forem compartilhadas, por exemplo, por vários encadeamentos ou usando bibliotecas vinculadas dinamicamente

Se você realmente deseja saber a quantidade de memória que seu aplicativo realmente usa, é necessário executá-lo em um criador de perfil. Por exemplo, valgrindvocê pode obter informações sobre a quantidade de memória usada e, mais importante, sobre possíveis vazamentos de memória em seu programa. A ferramenta heap profiler do valgrind é chamada 'massif':

Massif é um profiler de pilha. Ele realiza a criação de perfil de heap detalhado, capturando instantâneos regulares da pilha de um programa. Ele produz um gráfico mostrando o uso de heap ao longo do tempo, incluindo informações sobre quais partes do programa são responsáveis ​​pela maior parte das alocações de memória. O gráfico é complementado por um arquivo de texto ou HTML que inclui mais informações para determinar onde mais memória está sendo alocada. O Massif executa programas cerca de 20x mais lentos que o normal.

Conforme explicado na documentação do valgrind , você precisa executar o programa através do valgrind:

valgrind --tool=massif <executable> <arguments>

O Massif grava um despejo de instantâneos de uso de memória (por exemplo massif.out.12345). Eles fornecem, (1) uma linha do tempo de uso da memória, (2) para cada instantâneo, um registro de onde a memória do programa foi alocada. Uma ótima ferramenta gráfica para analisar esses arquivos é o massif-visualizer . Mas descobri que ms_printuma ferramenta simples baseada em texto enviada com o valgrind já é de grande ajuda.

Para encontrar vazamentos de memória, use a memcheckferramenta (padrão) do valgrind.


44
Para interpretar os resultados gerados pelo valgrind, posso recomendar o alleyoop. Não é muito chique e diz simplesmente o que você precisa saber para localizar fontes de vazamentos. Um bom par de utilitários.
Dan

6
O item (a) está correto. Há uma diferença entre as páginas usadas e a memória realmente alocada pelo aplicativo por meio de chamadas para malloc (), new etc. O uso residente mostra apenas a quantidade de memória paginada residente na RAM.
Jcoffland #

63
Isso realmente não diz como obter uso de memória usando o valgrind?
Matt Joiner

11
a ferramenta valgrind padrão, memcheck, é útil para detectar vazamentos de memória, mas não é realmente um criador de perfil de memória. Para isso, você quer valgrind --tool = massif.
Todd Freed

3
@DavidSchwartz Não vejo como sua declaração contradiz a minha. Tenho a sensação de que você está preocupado demais com o fato de eu estar "errado" do que realmente lendo o que estou dizendo. Meu argumento aqui é que o RSS é uma medida inadequada para o uso real da memória do aplicativo, e você está fazendo o mesmo ponto nas duas últimas frases. Realmente, o que você achou que era a razão de eu abrir o encolhimento do RSS em primeiro lugar? Para que você me explique de volta para me provar "errado" exatamente pela qual estou me referindo? Sua atitude em relação a mim é cansativa.
Ypnos 25/05

280

Experimente o comando pmap :

sudo pmap -x <process pid>

45
executar com sudo ou não dá erro e não mostra memória consumida.
Matt

22
Não existe no OSX (para quem vem aqui de google)
jcollum

3
Essa é uma resposta completa para a pergunta! ps. No meu shell, o pmap pode ler o processo sem o sudo.
MasterControlProgram

7
Re OS X (aparentemente não preocupação do OP), você pode ver alguns dados semelhantes usando VMMap (1)
JRG

nota: dá uma resposta completamente diferente degnome-system-monitor
ribamar

190

Difícil dizer com certeza, mas aqui estão duas coisas "próximas" que podem ajudar.

$ ps aux 

lhe dará tamanho virtual (VSZ)

Você também pode obter estatísticas detalhadas do sistema de arquivos / proc, acessando /proc/$pid/status

O mais importante é o VmSize, que deve estar próximo do que ps auxdá.

/ proc / 19420 $ status de cat
Nome: firefox
Estado: S (adormecido)
Tgid: 19420
Pid: 19420
PPid: 1
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
Tamanho: 256
Grupos: 4 6 20 24 25 29 30 44 46 107 109 115 115 124 1000 
VmPeak: 222956 kB
Tamanho: 212520 kB
VmLck: 0 kB
VmHWM: 127912 kB
VmRSS: 118768 kB
Dados vm: 170180 kB
VmStk: 228 kB
VmExe: 28 kB
VmLib: 35424 kB
VmPTE: 184 kB
Tópicos: 8
SigQ: 0/16382
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000020001000
SigCgt: 000000018000442f
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
Cpus_allowed: 03
Mems_allowed: 1
voluntary_ctxt_switches: 63422
nonvoluntary_ctxt_switches: 7171


21
Estou esquecendo de algo? A pergunta foi feita sobre como medir melhor o uso da memória por um processo, considerando que o VSZ e o RSS relatados no ps são enganosos. Sua resposta detalha como procurar o VSZ - o mesmo valor que foi mencionado como enganoso.
thomasrutter

16
@thomasrutter Sim, está faltando a pergunta original (rev 1), ela foi editada várias vezes e é bastante antiga (2008). A pergunta original acabou de perguntar como medir o uso de memória de um processo. No entanto, fique à vontade para editar perguntas e respostas, se as coisas estiverem desatualizadas. :)
DustinB

1
nota: dá uma resposta completamente diferente degnome-system-monitor
ribamar

131

Nas versões recentes do linux, use o subsistema smaps . Por exemplo, para um processo com um PID de 1234:

cat /proc/1234/smaps

Ele lhe dirá exatamente quanta memória está usando naquele momento. Mais importante, ele dividirá a memória em privada e compartilhada, para que você possa saber quanta memória sua instância do programa está usando, sem incluir a memória compartilhada entre várias instâncias do programa.


Eu acho que pmapé uma interface mais simples para ele.
Ribamar 6/07

126

Não há uma maneira fácil de calcular isso. Mas algumas pessoas tentaram obter boas respostas:


agradável gera uma lista limpa de memória e processo
Rubytastic

Muito bom, com um agrupamento bastante inteligente.
Rohmer 5/05

Sim, muito bom mesmo. Eu acho ps_meme smemmuito útil para medidas do usuário final, enquanto por exemplo. pmapA saída muito detalhada é voltada para desenvolvedores ... permite recuperar o uso de memória do Firefox para cada fonte, complementos, bibliotecas por ex. Obrigado a todos exp. @Bash, @thomasruther.
precisa saber é

esta é até agora o único a coincidir com a saída degnome-system-monitor
Ribamar

110

Use smem , que é uma alternativa ao ps que calcula o USS e o PSS por processo. O que você quer é provavelmente o PSS.

  • USS - tamanho único do conjunto. Essa é a quantidade de memória não compartilhada exclusiva para esse processo (pense nela como U para memória exclusiva ). Não inclui memória compartilhada. Assim, esta vontade sob -report a quantidade de memória que um processo usos, mas é útil quando você quer ignorar memória compartilhada.

  • PSS - tamanho proporcional do conjunto. Isso é o que você quer. Ele adiciona a memória exclusiva (USS), juntamente com uma proporção de sua memória compartilhada dividida pelo número de processos que compartilham essa memória. Assim, ele fornecerá uma representação precisa de quanta memória física real está sendo usada por processo - com a memória compartilhada realmente representada como compartilhada. Pense no P sendo a memória física .

Como isso se compara ao RSS, conforme relatado por ps e outros utilitários:

  • RSS - Tamanho do conjunto residente. Essa é a quantidade de memória compartilhada mais a memória não compartilhada usada por cada processo. Se algum processo compartilhar memória, isso registrará em excesso a quantidade de memória realmente usada, porque a mesma memória compartilhada será contada mais de uma vez - aparecendo novamente no outro processo que compartilha a mesma memória. Portanto, é relativamente pouco confiável, especialmente quando os processos de alta memória possuem muitos garfos - o que é comum em um servidor, com coisas como processos Apache ou PHP (fastcgi / FPM).

Nota: o smem também pode (opcionalmente) gerar gráficos como gráficos de pizza e similares. OMI, você não precisa disso. Se você quiser apenas usá-lo na linha de comando como se estivesse usando o ps -A v, não precisará instalar a dependência recomendada pelo python-matplotlib.


2
Um ponto crítico sobre o RSS é que a maioria dos aplicativos hoje em dia compartilha muitas páginas de código. Toda biblioteca compartilhada (por exemplo, libc e libstdc ++) será contada para todos os processos que a utilizarem. E se houver várias instâncias de um processo em execução, todo esse código será contado duas vezes.
David C.

1
Precisamente, é por isso que o RSS faz um relatório excessivo em termos de memória física real por processo.
thomasrutter

3
smem é o que eu precisava. Ao executá-lo com -t sempre que inicio uma nova instância do processo, posso ver a memória que cada instância consome. Para chrome: smem -t -P '/ opt / google / chrome'
xtian

Estou tendo dificuldade em encontrar documentação para o smem .. isso gera em bytes, kilobytes ou megabytes por padrão?
ZN13 01/06

4
TL; DR: USS = Quantidade de memória física que será liberada se o processo for morto, PSS = Quantidade de memória física que esse processo precisa do sistema se nenhum processo existente for morto, RSS = Quantidade de memória física acessível por esse processo (mas nem sempre o acesso exclusivo).
Mikko Rantalainen

95
ps -eo size,pid,user,command --sort -size | \
    awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' |\
    cut -d "" -f2 | cut -d "-" -f1

Use isso como root e você poderá obter uma saída clara para o uso da memória em cada processo.

EXEMPLO DE SAÍDA:

     0.00 Mb COMMAND 
  1288.57 Mb /usr/lib/firefox
   821.68 Mb /usr/lib/chromium/chromium 
   762.82 Mb /usr/lib/chromium/chromium 
   588.36 Mb /usr/sbin/mysqld 
   547.55 Mb /usr/lib/chromium/chromium 
   523.92 Mb /usr/lib/tracker/tracker
   476.59 Mb /usr/lib/chromium/chromium 
   446.41 Mb /usr/bin/gnome
   421.62 Mb /usr/sbin/libvirtd 
   405.11 Mb /usr/lib/chromium/chromium 
   302.60 Mb /usr/lib/chromium/chromium 
   291.46 Mb /usr/lib/chromium/chromium 
   284.56 Mb /usr/lib/chromium/chromium 
   238.93 Mb /usr/lib/tracker/tracker
   223.21 Mb /usr/lib/chromium/chromium 
   197.99 Mb /usr/lib/chromium/chromium 
   194.07 Mb conky 
   191.92 Mb /usr/lib/chromium/chromium 
   190.72 Mb /usr/bin/mongod 
   169.06 Mb /usr/lib/chromium/chromium 
   155.11 Mb /usr/bin/gnome
   136.02 Mb /usr/lib/chromium/chromium 
   125.98 Mb /usr/lib/chromium/chromium 
   103.98 Mb /usr/lib/chromium/chromium 
    93.22 Mb /usr/lib/tracker/tracker
    89.21 Mb /usr/lib/gnome
    80.61 Mb /usr/bin/gnome
    77.73 Mb /usr/lib/evolution/evolution
    76.09 Mb /usr/lib/evolution/evolution
    72.21 Mb /usr/lib/gnome
    69.40 Mb /usr/lib/evolution/evolution
    68.84 Mb nautilus
    68.08 Mb zeitgeist
    60.97 Mb /usr/lib/tracker/tracker
    59.65 Mb /usr/lib/evolution/evolution
    57.68 Mb apt
    55.23 Mb /usr/lib/gnome
    53.61 Mb /usr/lib/evolution/evolution
    53.07 Mb /usr/lib/gnome
    52.83 Mb /usr/lib/gnome
    51.02 Mb /usr/lib/udisks2/udisksd 
    50.77 Mb /usr/lib/evolution/evolution
    50.53 Mb /usr/lib/gnome
    50.45 Mb /usr/lib/gvfs/gvfs
    50.36 Mb /usr/lib/packagekit/packagekitd 
    50.14 Mb /usr/lib/gvfs/gvfs
    48.95 Mb /usr/bin/Xwayland :1024 
    46.21 Mb /usr/bin/gnome
    42.43 Mb /usr/bin/zeitgeist
    42.29 Mb /usr/lib/gnome
    41.97 Mb /usr/lib/gnome
    41.64 Mb /usr/lib/gvfs/gvfsd
    41.63 Mb /usr/lib/gvfs/gvfsd
    41.55 Mb /usr/lib/gvfs/gvfsd
    41.48 Mb /usr/lib/gvfs/gvfsd
    39.87 Mb /usr/bin/python /usr/bin/chrome
    37.45 Mb /usr/lib/xorg/Xorg vt2 
    36.62 Mb /usr/sbin/NetworkManager 
    35.63 Mb /usr/lib/caribou/caribou 
    34.79 Mb /usr/lib/tracker/tracker
    33.88 Mb /usr/sbin/ModemManager 
    33.77 Mb /usr/lib/gnome
    33.61 Mb /usr/lib/upower/upowerd 
    33.53 Mb /usr/sbin/gdm3 
    33.37 Mb /usr/lib/gvfs/gvfsd
    33.36 Mb /usr/lib/gvfs/gvfs
    33.23 Mb /usr/lib/gvfs/gvfs
    33.15 Mb /usr/lib/at
    33.15 Mb /usr/lib/at
    30.03 Mb /usr/lib/colord/colord 
    29.62 Mb /usr/lib/apt/methods/https 
    28.06 Mb /usr/lib/zeitgeist/zeitgeist
    27.29 Mb /usr/lib/policykit
    25.55 Mb /usr/lib/gvfs/gvfs
    25.55 Mb /usr/lib/gvfs/gvfs
    25.23 Mb /usr/lib/accountsservice/accounts
    25.18 Mb /usr/lib/gvfs/gvfsd 
    25.15 Mb /usr/lib/gvfs/gvfs
    25.15 Mb /usr/lib/gvfs/gvfs
    25.12 Mb /usr/lib/gvfs/gvfs
    25.10 Mb /usr/lib/gnome
    25.10 Mb /usr/lib/gnome
    25.07 Mb /usr/lib/gvfs/gvfsd 
    24.99 Mb /usr/lib/gvfs/gvfs
    23.26 Mb /usr/lib/chromium/chromium 
    22.09 Mb /usr/bin/pulseaudio 
    19.01 Mb /usr/bin/pulseaudio 
    18.62 Mb (sd
    18.46 Mb (sd
    18.30 Mb /sbin/init 
    18.17 Mb /usr/sbin/rsyslogd 
    17.50 Mb gdm
    17.42 Mb gdm
    17.09 Mb /usr/lib/dconf/dconf
    17.09 Mb /usr/lib/at
    17.06 Mb /usr/lib/gvfs/gvfsd
    16.98 Mb /usr/lib/at
    16.91 Mb /usr/lib/gdm3/gdm
    16.86 Mb /usr/lib/gvfs/gvfsd
    16.86 Mb /usr/lib/gdm3/gdm
    16.85 Mb /usr/lib/dconf/dconf
    16.85 Mb /usr/lib/dconf/dconf
    16.73 Mb /usr/lib/rtkit/rtkit
    16.69 Mb /lib/systemd/systemd
    13.13 Mb /usr/lib/chromium/chromium 
    13.13 Mb /usr/lib/chromium/chromium 
    10.92 Mb anydesk 
     8.54 Mb /sbin/lvmetad 
     7.43 Mb /usr/sbin/apache2 
     6.82 Mb /usr/sbin/apache2 
     6.77 Mb /usr/sbin/apache2 
     6.73 Mb /usr/sbin/apache2 
     6.66 Mb /usr/sbin/apache2 
     6.64 Mb /usr/sbin/apache2 
     6.63 Mb /usr/sbin/apache2 
     6.62 Mb /usr/sbin/apache2 
     6.51 Mb /usr/sbin/apache2 
     6.25 Mb /usr/sbin/apache2 
     6.22 Mb /usr/sbin/apache2 
     3.92 Mb bash 
     3.14 Mb bash 
     2.97 Mb bash 
     2.95 Mb bash 
     2.93 Mb bash 
     2.91 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.86 Mb bash 
     2.84 Mb bash 
     2.84 Mb bash 
     2.45 Mb /lib/systemd/systemd
     2.30 Mb (sd
     2.28 Mb /usr/bin/dbus
     1.84 Mb /usr/bin/dbus
     1.46 Mb ps 
     1.21 Mb openvpn hackthebox.ovpn 
     1.16 Mb /sbin/dhclient 
     1.16 Mb /sbin/dhclient 
     1.09 Mb /lib/systemd/systemd 
     0.98 Mb /sbin/mount.ntfs /dev/sda3 /media/n0bit4/Data 
     0.97 Mb /lib/systemd/systemd 
     0.96 Mb /lib/systemd/systemd 
     0.89 Mb /usr/sbin/smartd 
     0.77 Mb /usr/bin/dbus
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.76 Mb su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.75 Mb sudo su 
     0.74 Mb /usr/bin/dbus
     0.71 Mb /usr/lib/apt/methods/http 
     0.68 Mb /bin/bash /usr/bin/mysqld_safe 
     0.68 Mb /sbin/wpa_supplicant 
     0.66 Mb /usr/bin/dbus
     0.61 Mb /lib/systemd/systemd
     0.54 Mb /usr/bin/dbus
     0.46 Mb /usr/sbin/cron 
     0.45 Mb /usr/sbin/irqbalance 
     0.43 Mb logger 
     0.41 Mb awk { hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" } 
     0.40 Mb /usr/bin/ssh
     0.34 Mb /usr/lib/chromium/chrome
     0.32 Mb cut 
     0.32 Mb cut 
     0.00 Mb [kthreadd] 
     0.00 Mb [ksoftirqd/0] 
     0.00 Mb [kworker/0:0H] 
     0.00 Mb [rcu_sched] 
     0.00 Mb [rcu_bh] 
     0.00 Mb [migration/0] 
     0.00 Mb [lru
     0.00 Mb [watchdog/0] 
     0.00 Mb [cpuhp/0] 
     0.00 Mb [cpuhp/1] 
     0.00 Mb [watchdog/1] 
     0.00 Mb [migration/1] 
     0.00 Mb [ksoftirqd/1] 
     0.00 Mb [kworker/1:0H] 
     0.00 Mb [cpuhp/2] 
     0.00 Mb [watchdog/2] 
     0.00 Mb [migration/2] 
     0.00 Mb [ksoftirqd/2] 
     0.00 Mb [kworker/2:0H] 
     0.00 Mb [cpuhp/3] 
     0.00 Mb [watchdog/3] 
     0.00 Mb [migration/3] 
     0.00 Mb [ksoftirqd/3] 
     0.00 Mb [kworker/3:0H] 
     0.00 Mb [kdevtmpfs] 
     0.00 Mb [netns] 
     0.00 Mb [khungtaskd] 
     0.00 Mb [oom_reaper] 
     0.00 Mb [writeback] 
     0.00 Mb [kcompactd0] 
     0.00 Mb [ksmd] 
     0.00 Mb [khugepaged] 
     0.00 Mb [crypto] 
     0.00 Mb [kintegrityd] 
     0.00 Mb [bioset] 
     0.00 Mb [kblockd] 
     0.00 Mb [devfreq_wq] 
     0.00 Mb [watchdogd] 
     0.00 Mb [kswapd0] 
     0.00 Mb [vmstat] 
     0.00 Mb [kthrotld] 
     0.00 Mb [ipv6_addrconf] 
     0.00 Mb [acpi_thermal_pm] 
     0.00 Mb [ata_sff] 
     0.00 Mb [scsi_eh_0] 
     0.00 Mb [scsi_tmf_0] 
     0.00 Mb [scsi_eh_1] 
     0.00 Mb [scsi_tmf_1] 
     0.00 Mb [scsi_eh_2] 
     0.00 Mb [scsi_tmf_2] 
     0.00 Mb [scsi_eh_3] 
     0.00 Mb [scsi_tmf_3] 
     0.00 Mb [scsi_eh_4] 
     0.00 Mb [scsi_tmf_4] 
     0.00 Mb [scsi_eh_5] 
     0.00 Mb [scsi_tmf_5] 
     0.00 Mb [bioset] 
     0.00 Mb [kworker/1:1H] 
     0.00 Mb [kworker/3:1H] 
     0.00 Mb [kworker/0:1H] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [kdmflush] 
     0.00 Mb [bioset] 
     0.00 Mb [jbd2/sda5
     0.00 Mb [ext4
     0.00 Mb [kworker/2:1H] 
     0.00 Mb [kauditd] 
     0.00 Mb [bioset] 
     0.00 Mb [drbd
     0.00 Mb [irq/27
     0.00 Mb [i915/signal:0] 
     0.00 Mb [i915/signal:1] 
     0.00 Mb [i915/signal:2] 
     0.00 Mb [ttm_swap] 
     0.00 Mb [cfg80211] 
     0.00 Mb [kworker/u17:0] 
     0.00 Mb [hci0] 
     0.00 Mb [hci0] 
     0.00 Mb [kworker/u17:1] 
     0.00 Mb [iprt
     0.00 Mb [iprt
     0.00 Mb [kworker/1:0] 
     0.00 Mb [kworker/3:0] 
     0.00 Mb [kworker/0:0] 
     0.00 Mb [kworker/2:0] 
     0.00 Mb [kworker/u16:0] 
     0.00 Mb [kworker/u16:2] 
     0.00 Mb [kworker/3:2] 
     0.00 Mb [kworker/2:1] 
     0.00 Mb [kworker/1:2] 
     0.00 Mb [kworker/0:2] 
     0.00 Mb [kworker/2:2] 
     0.00 Mb [kworker/0:1] 
     0.00 Mb [scsi_eh_6] 
     0.00 Mb [scsi_tmf_6] 
     0.00 Mb [usb
     0.00 Mb [bioset] 
     0.00 Mb [kworker/3:1] 
     0.00 Mb [kworker/u16:1] 

1
Alguma maneira de filtrar a lista para ter apenas processos que usam mais de 25% da memória por 30 anos? Estou tentando ver processos em fuga, como o navegador Chrome ao usar um depurador PHPEclipse.
Stephane

esse filtro seria incrível #
Aleix

1
Vou postar isso assim que puder.
Lokendra Singh Rawat

2
Ótimo! Mas o loop deve começar x=2também para gerar pid e user.
Boris Brodski

70

Que tal time?

Não o Bash embutido, timemas o que você pode encontrar which time, por exemplo/usr/bin/time

Aqui está o que ele cobre, de maneira simples ls:

$ /usr/bin/time --verbose ls
(...)
Command being timed: "ls"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 2372
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 1
Minor (reclaiming a frame) page faults: 121
Voluntary context switches: 2
Involuntary context switches: 9
Swaps: 0
File system inputs: 256
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

Eu também sou. É a maneira que eu uso para tarefas em seu perfil no powercron.eu :)
Moonchild

5
brew install gnu-timeentão use gtimese você estiver no macOS.
Nobu

4
Desvantagem: Não obterá os resultados até que o processo conclua sua execução. Não pode ser usado para monitoramento em tempo real do processo em execução.
precisa

/ usr / bin / time -f '% M'
infomaniac 8/08/18

1
Você também pode invocá-lo usando \ time (com uma barra invertida para impedir o uso do tempo interno do shell).
Raúl Salinas-Monteagudo 26/11

39

Este é um excelente resumo das ferramentas e problemas: archive.org link

Vou citar, para que mais desenvolvedores o leiam.

Se você deseja analisar o uso de memória de todo o sistema ou analisar completamente o uso de memória de um aplicativo (não apenas o uso de heap), use o exmap . Para análise de todo o sistema, encontre processos com o maior uso efetivo, consumam mais memória na prática, encontre processos com o maior uso gravável, crie mais dados (e, portanto, possivelmente vaze ou seja muito ineficaz no uso de dados). Selecione esse aplicativo e analise seus mapeamentos na segunda exibição de lista. Veja a seção exmap para mais detalhes. Use também o xrestop para verificar o alto uso dos recursos do X, especialmente se o processo do servidor X consumir muita memória. Veja a seção xrestop para detalhes.

Se você deseja detectar vazamentos, use valgrind ou possivelmente kmtrace .

Se você deseja analisar o uso de heap (malloc etc.) de um aplicativo, execute-o no memprof ou com kmtrace , perfile o aplicativo e pesquise na árvore de chamadas de funções as maiores alocações. Veja suas seções para mais detalhes.


28

Além das soluções listadas em tuas respostas, você pode usar o comando Linux "top"; Ele fornece uma visualização dinâmica em tempo real do sistema em execução, fornece o uso da CPU e da memória, para todo o sistema e para todos os programas, em porcentagem:

top

filtrar por um programa pid:

top -p <PID>

para filtrar por um nome de programa:

top | grep <PROCESS NAME>

"top" também fornece alguns campos como:

VIRT - Imagem virtual (kb): a quantidade total de memória virtual usada pela tarefa

RES - Tamanho do residente (kb): a memória física não trocada que uma tarefa usou; RES = CÓDIGO + DADOS.

DADOS - Tamanho dos dados + da pilha (kb): a quantidade de memória física dedicada a outro código que não o executável, também conhecido como tamanho do 'conjunto de residentes de dados' ou DRS.

SHR - Tamanho da memória compartilhada (kb): a quantidade de memória compartilhada usada por uma tarefa. Simplesmente reflete a memória que poderia ser potencialmente compartilhada com outros processos.

Referência aqui .


20

Não existe uma única resposta para isso, porque você não pode apontar com precisão a quantidade de memória que um processo usa. A maioria dos processos no linux usa bibliotecas compartilhadas. Por exemplo, digamos que você queira calcular o uso de memória para o processo 'ls'. Você conta apenas a memória usada pelo executável 'ls' (se você puder isolá-lo)? E a libc? Ou todas essas outras bibliotecas necessárias para executar 'ls'?

linux-gate.so.1 =>  (0x00ccb000)
librt.so.1 => /lib/librt.so.1 (0x06bc7000)
libacl.so.1 => /lib/libacl.so.1 (0x00230000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00162000)
libc.so.6 => /lib/libc.so.6 (0x00b40000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00cb4000)
/lib/ld-linux.so.2 (0x00b1d000)
libattr.so.1 => /lib/libattr.so.1 (0x00229000)
libdl.so.2 => /lib/libdl.so.2 (0x00cae000)
libsepol.so.1 => /lib/libsepol.so.1 (0x0011a000)

Você pode argumentar que eles são compartilhados por outros processos, mas 'ls' não podem ser executados no sistema sem que eles sejam carregados.

Além disso, se você precisar saber quanta memória um processo precisa para fazer o planejamento da capacidade, será necessário calcular quanto cada cópia adicional do processo usa. Eu acho que / proc / PID / status pode fornecer informações suficientes sobre o uso da memória em uma única vez. Por outro lado, o valgrind fornecerá um perfil melhor do uso da memória durante toda a vida útil do programa


Eu estou tentando descobrir o quanto de memória um processo está tomando em uma VM e quer usar isso para limite de memória de configuração em Kubernetes, eu concordo sobre esta resposta, por isso vai estar usando a memória mostrado porpmap
Deepak Deore

16

Se o seu código estiver em C ou C ++, você poderá usá- getrusage()lo, retornando várias estatísticas sobre o uso da memória e do tempo do seu processo.

Porém, nem todas as plataformas suportam isso e retornarão 0 valores para as opções de uso de memória.

Em vez disso, você pode ver o arquivo virtual criado em /proc/[pid]/statm(onde [pid]é substituído pelo seu ID do processo. Você pode obtê-lo em getpid()).

Este arquivo será semelhante a um arquivo de texto com 7 números inteiros. Você provavelmente está mais interessado nos números primeiro (todo o uso de memória) e sexto (uso de memória de dados) neste arquivo.


Observe que isso não é suportado em todas as plataformas.
CashCow

De acordo com a página de manual do Linux ( linux.die.net/man/2/getrusage ), getrusage faz parte das especificações SVr4, 4.3BSD e POSIX.1-2001 (observando que o POSIX especifica apenas os campos utime e stime.) I não seria de esperar que o trabalho em plataformas não-UNIX (exceto, talvez, através de um ambiente como Cygwin que fornece capacidades UNIX para outras plataformas.)
David C.

@DavidC. o OP está perguntando sobre o Linux.
Alexis Wilke

@CashCow, você quis dizer getpid(), porque não conheço uma getprocessid()função em C / C ++ no Linux.
Alexis Wilke

12

O Valgrind pode mostrar informações detalhadas, mas diminui significativamente o aplicativo de destino e, na maioria das vezes, altera o comportamento do aplicativo.
O Exmap era algo que eu ainda não sabia, mas parece que você precisa de um módulo do kernel para obter as informações, o que pode ser um obstáculo.

Suponho que o que todos querem saber o "uso da memória" do WRT é o seguinte ...
No linux, a quantidade de memória física que um único processo pode usar pode ser dividida em categorias a seguir.

  • Ma memória mapeada anônima

    • .p private
      • .d sujo == pilha malloc / mmapped e pilha de memória alocada e gravada
      • .c limpa == memória de heap e pilha malloc / mmapped uma vez alocada, gravada e liberada, mas ainda não recuperada
    • .s compartilhou
      • .d sujo == heap malloc / mmaped pode ser copiado na gravação e compartilhado entre processos (editado)
      • .c clean == heap malloc / mmaped pode ser copiado na gravação e compartilhado entre processos (editado)
  • Mn nomeado memória mapeada

    • .p private
      • .d sujo == arquivo mmapped memória escrita privada
      • .c clean == programa / biblioteca mapeados texto privado mapeado
    • .s compartilhou
      • .d sujo == arquivo mmapped memória escrita compartilhada
      • .c clean == texto da biblioteca mapeada compartilhada mapeada

O utilitário incluído no Android chamado showmap é bastante útil

virtual                    shared   shared   private  private
size     RSS      PSS      clean    dirty    clean    dirty    object
-------- -------- -------- -------- -------- -------- -------- ------------------------------
       4        0        0        0        0        0        0 0:00 0                  [vsyscall]
       4        4        0        4        0        0        0                         [vdso]
      88       28       28        0        0        4       24                         [stack]
      12       12       12        0        0        0       12 7909                    /lib/ld-2.11.1.so
      12        4        4        0        0        0        4 89529                   /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
      28        0        0        0        0        0        0 86661                   /usr/lib/gconv/gconv-modules.cache
       4        0        0        0        0        0        0 87660                   /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
       4        0        0        0        0        0        0 89528                   /usr/lib/locale/en_US.utf8/LC_TELEPHONE
       4        0        0        0        0        0        0 89527                   /usr/lib/locale/en_US.utf8/LC_ADDRESS
       4        0        0        0        0        0        0 87717                   /usr/lib/locale/en_US.utf8/LC_NAME
       4        0        0        0        0        0        0 87873                   /usr/lib/locale/en_US.utf8/LC_PAPER
       4        0        0        0        0        0        0 13879                   /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
       4        0        0        0        0        0        0 89526                   /usr/lib/locale/en_US.utf8/LC_MONETARY
       4        0        0        0        0        0        0 89525                   /usr/lib/locale/en_US.utf8/LC_TIME
       4        0        0        0        0        0        0 11378                   /usr/lib/locale/en_US.utf8/LC_NUMERIC
    1156        8        8        0        0        4        4 11372                   /usr/lib/locale/en_US.utf8/LC_COLLATE
     252        0        0        0        0        0        0 11321                   /usr/lib/locale/en_US.utf8/LC_CTYPE
     128       52        1       52        0        0        0 7909                    /lib/ld-2.11.1.so
    2316       32       11       24        0        0        8 7986                    /lib/libncurses.so.5.7
    2064        8        4        4        0        0        4 7947                    /lib/libdl-2.11.1.so
    3596      472       46      440        0        4       28 7933                    /lib/libc-2.11.1.so
    2084        4        0        4        0        0        0 7995                    /lib/libnss_compat-2.11.1.so
    2152        4        0        4        0        0        0 7993                    /lib/libnsl-2.11.1.so
    2092        0        0        0        0        0        0 8009                    /lib/libnss_nis-2.11.1.so
    2100        0        0        0        0        0        0 7999                    /lib/libnss_files-2.11.1.so
    3752     2736     2736        0        0      864     1872                         [heap]
      24       24       24        0        0        0       24 [anon]
     916      616      131      584        0        0       32                         /bin/bash
-------- -------- -------- -------- -------- -------- -------- ------------------------------
   22816     4004     3005     1116        0      876     2012 TOTAL

10

Mais três métodos para tentar:

  1. ps aux --sort pmem
    Classifica a saída por %MEM.
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    Classifica usando tubos.
  3. top -a
    Inicia a classificação superior por %MEM

(Extraído daqui )


2
tope provavelmente os outros não dão uma representação precisa da memória realmente usada pelo processo. Por exemplo, tenho 64GiB de RAM e 10 postgresprocessos, cada um relatando 16GiB RES e 25% MEM. É claro que nem todos podem usar 25% ... Cada um também possui 15GiB SHR, e parece que eles estão compartilhando isso.
sudo

8
#!/bin/ksh
#
# Returns total memory used by process $1 in kb.
#
# See /proc/NNNN/smaps if you want to do something
# more interesting.
#

IFS=$'\n'

for line in $(</proc/$1/smaps)
do
   [[ $line =~ ^Size:\s+(\S+) ]] && ((kb += ${.sh.match[1]}))
done

print $kb

5
O ksh é um shell padrão. Pode não ser instalado por padrão nas distribuições linux para usuários de desktop ou para propósitos minimalistas, mas é apenas um comando de distância em quase qualquer SO unix- / linux. (ou seja, em todos os BSDs, em tudo real UNIX, no RHEL, no SLES, no Debian, no Ubuntu, em OSX)
Florian Heigl

Este arquivo é acessível, por padrão, apenas para o usuário root.
Dmitry Ginzburg

A seguir, é reescrito acima sed | awke funciona no Busybox v1.23.2: sed -n 's/^Size:\s\+\(\S\+\) .*/\1/p' /proc/$1/smaps | awk '{s+=$1} END {print s}'
Ján Sáreník

1
@Catskul - O padrão POSIX especifica seu shell padrão como um subconjunto estrito do shell Korn, uma versão aprimorada do shell Bourne.
ceph3us

8

Estou usando htop; é um programa de console muito bom, semelhante ao Windows Task Manager.


Eu usei htope é melhor que o top, mas ainda assim ele mostra todos os tópicos de aplicativos diferentes sem agrupá-los, tornando-o quase tão inútil quanto o top.
sorin

1
$ htop -p $ (pgrep <nome do processo> | xargs | tr '' ',')
AAAfarmclub

6

Se o processo não estiver consumindo muita memória (porque você espera que seja esse o caso, ou algum outro comando tenha fornecido essa indicação inicial), e o processo possa suportar a interrupção por um curto período de tempo, tente use o comando gcore.

gcore <pid>

Verifique o tamanho do arquivo principal gerado para ter uma boa idéia de quanta memória um determinado processo está usando.

Isso não funcionará muito bem se o processo estiver usando centenas de megas ou shows, pois a geração do núcleo pode levar vários segundos ou minutos para ser criada, dependendo do desempenho de E / S. Durante a criação do núcleo, o processo é interrompido (ou "congelado") para evitar alterações de memória. Por isso tem cuidado.

Verifique também se o ponto de montagem em que o núcleo é gerado possui bastante espaço em disco e se o sistema não reagirá negativamente ao arquivo principal que está sendo criado nesse diretório específico.


6

Estou usando o Arch Linux e existe um pacote maravilhoso chamado ps_mem

ps_mem -p <pid>

Saída de exemplo

$ ps_mem -S -p $(pgrep firefox)

Private   +   Shared  =  RAM used   Swap used   Program

355.0 MiB +  38.7 MiB = 393.7 MiB    35.9 MiB   firefox
---------------------------------------------
                        393.7 MiB    35.9 MiB
=============================================

5

Abaixo da linha de comando, você terá a memória total usada pelos vários processos em execução na máquina Linux em MB

ps -eo size,pid,user,command --sort -size | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | awk '{total=total + $1} END {print total}'

5

Um bom teste para o uso mais "real" é abrir o aplicativo, executar vmstat -se verificar a estatística "memória ativa". Feche o aplicativo, aguarde alguns segundos e execute vmstat -snovamente. No entanto, muita memória ativa foi liberada estava evidentemente em uso pelo aplicativo.


3
Como isso seria melhor que o ps? Ele vem com toda a limitação do ps e é ainda mais imprecisas ...
Lester Cheung

Um sistema Unix típico tem muitos processos iniciando e finalizando o tempo todo. Você não pode prever sua RAM livre.
Raúl Salinas-Monteagudo 26/11

4

Obter valgrind. dê a ele seu programa para ser executado e ele informará bastante sobre o uso de memória.

Isso se aplica apenas ao caso de um programa que é executado por algum tempo e para. Não sei se o valgrind pode colocar as mãos em um processo já em execução ou não deve parar processos como daemons.


Não, não é possível "anexar" o valgrind a um processo em execução. Isso é por design.
Dima Tisnek

3

Edit: isso funciona 100% bem apenas quando o consumo de memória aumenta

Se você deseja monitorar o uso da memória por determinado processo (ou grupo de nomes comuns de compartilhamento processados, por exemplo google-chrome, você pode usar meu script bash:

while true; do ps aux | awk ‚{print $5, $11}’ | grep chrome | sort -n > /tmp/a.txt; sleep 1; diff /tmp/{b,a}.txt; mv /tmp/{a,b}.txt; done;

isso procurará continuamente as alterações e as imprimirá.

insira a descrição da imagem aqui


3

Se você deseja algo mais rápido que criar um perfil com o Valgrind e seu kernel é mais antigo e não pode usar smaps, um ps com as opções para mostrar o conjunto residente do processo (com ps -o rss,command) pode fornecer uma rápida e razoável _aproximation_quantidade real de memória não trocada em uso.


3

Eu sugiro que você use no topo. Você pode encontrar tudo sobre isso nesta página . Ele é capaz de fornecer todo o KPI necessário para seus processos e também pode capturar em um arquivo.


2
Para mostrar o PSIZE ["tamanho proporcional da memória deste processo (ou usuário)), inicie sobre o uso atop -R. Para mostrar um resumo por push do usuário p, para classificar por uso de memória, pressione 'M' de dentro para cima. Isso fornece números semelhantes ao smem.
Markus Strauss


1

Outro voto para aqui, mas gostaria de acrescentar que você pode usar uma ferramenta como o Alleyoop para ajudá-lo a interpretar os resultados gerados pelo valgrind.

Eu uso as duas ferramentas o tempo todo e sempre tenho código enxuto e sem vazamentos para mostrar com orgulho;)


1

Embora essa pergunta pareça ser sobre o exame dos processos em execução no momento, eu queria ver o pico de memória usado por um aplicativo do início ao fim. Além do valgrind, você pode usar o tstime , que é muito mais simples. Ele mede o uso de memória "highwater" (RSS e virtual). A partir desta resposta .


A maioria dos aplicativos - ou seja, aqueles que usam malloc () e bibliotecas de memória semelhantes a malloc - não retornam páginas ao sistema operacional até a finalização do processo. Portanto, a quantidade que você vê com o PS (ou qualquer outra ferramenta que não afunda a pilha do processo) será a marca d'água máxima.
David C.

0

Com base na resposta a uma pergunta relacionada .

Você pode usar o SNMP para obter a memória e o uso da CPU de um processo em um dispositivo específico da rede :)

Requisitos:

  • o dispositivo que está executando o processo deve ter o snmp instalado e em execução
  • O snmp deve ser configurado para aceitar solicitações de onde você executará o script abaixo (ele pode ser configurado no snmpd.conf)
  • você deve saber a identificação do processo (pid) do processo que deseja monitorar

Notas:

  • HOST-RESOURCES-MIB :: hrSWRunPerfCPU é o número de centi-segundos dos recursos de CPU do sistema total consumidos por esse processo. Observe que, em um sistema com vários processadores, esse valor pode aumentar em mais de um centi-segundo em um centi-segundo do tempo real (relógio de parede).

  • HOST-RESOURCES-MIB :: hrSWRunPerfMem é a quantidade total de memória real do sistema alocada para esse processo.

**

Script de monitoramento de processo:

**

echo "IP: "
read ip
echo "specfiy pid: "
read pid
echo "interval in seconds:"
read interval

while [ 1 ]
do
    date
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfCPU.$pid
    snmpget -v2c -c public $ip HOST-RESOURCES-MIB::hrSWRunPerfMem.$pid
    sleep $interval;
done

0

/ prox / xxx / numa_maps fornece algumas informações lá: N0 = ??? N1 = ??? Mas esse resultado pode ser menor que o resultado real, pois conta apenas os que foram tocados.


-1

Use a ferramenta GUI embutida ' monitor do sistema ' disponível no ubuntu


1
Pelo menos desde 16.04 isso funciona muito bem. É muito parecido com o topo, porém, a memória usada não é extremamente preciso ...
Alexis Wilke
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.