Como medir o uso total de RAM de um programa no Windows?

7

Eu estava comparando o uso de memória de diferentes navegadores portáteis, mas essa questão é geral para todos os programas que se abrem em vários subprocessos no gerenciador de tarefas.

Veja a captura de tela do Explorador de Processos da Sysinternals abaixo:

O Firefox, por exemplo, é aberto em apenas um processo, enquanto o Google Chrome inicia vários processos para cada guia.

Então, como posso obter o uso total de RAM para todos os processos abertos por um programa? (aqui para o Google Chrome, por exemplo).

Claro que eu poderia usar uma calculadora e calcular a soma ... mas deve haver uma maneira mais conveniente!

    
por UdeF 28.03.2015 / 18:33

3 respostas

12

A resposta geral é: Você não pode, não com precisão.

Supondo que você esteja perguntando sobre RAM (memória física) e não virtual - o Windows publica dois contadores relevantes para cada processo, o conjunto de trabalho total e o conjunto de trabalho particular (para o processo). (PerfMon irá mostrar-lhe estes). Gerenciador de Tarefas mostra o "privado" e "compartilhado" (somados estes dariam o total). Process Explorer mostra como "Working Set" (o total), "WS Private", "WS Shareable" e "WS Shared". ProcExp faz um pouco de "deep digging" para encontrar os dois últimos.

O "compartilhado", ou a parte compartilhada do total, é o que causa os problemas.

Usando os termos do Process Explorer, "Compartilhável" mostra RAM que foi alocada para o processo, mas que é pelo menos potencialmente compartilhada com outros processos. E "Compartilhado" é o subconjunto do que realmente está sendo compartilhado, por pelo menos um outro processo.

O problema é que você não sabe quantos ou quais processos estão realmente compartilhando-os. Adicionar todos os números "Compartilhável" ou "Compartilhado" fornecerá um total maior que a realidade, porque as páginas compartilhadas serão contadas em todos os processos que as compartilham. Nem todo processo, mesmo os processos que executam o mesmo programa (como o Chrome), necessariamente estarão compartilhando as mesmas páginas do espaço total de endereços.

Para um conjunto de processos que executam o mesmo .exe, como o do Chrome: adicionando todos os contadores "WS Private" e adicionando a esse total a maior parte de qualquer "WS compartilhável" da instância do Chrome, você receberá para um valor mínimo ... mas o real pode ser maior.

O Chrome tem esse bom recurso de auto-relato mencionado por ge0rdi. Os contadores que você deseja são os que estão em "Memória". O Chrome na minha máquina não concorda exatamente com o que o sistema operacional informa, mas é próximo o suficiente para todos os usos práticos.

Outra coisa a considerar é que o "uso da memória" de qualquer processo, ou subconjunto de processos, em um sistema operacional de memória virtual é extremamente dependente do comportamento do processo e da pressão da RAM. Executá-lo em um sistema com mais ou menos RAM, ou com mais ou menos outras coisas correndo e exigindo RAM, e os números serão muito diferentes. Portanto, não há um número fixo de quanta RAM um determinado processo "precisa". Por isso, mesmo "observe sua RAM disponível, feche todas as instâncias do Chrome e veja o quanto a RAM disponível aumenta" não é um bom teste. O sistema operacional pode atribuir parte da RAM liberada a outros processos, principalmente se estiverem ocupados.

    
por 28.03.2015 / 22:09
10

Eu não sei como fazer isso em geral, mas para medir o uso total de memória do Chrome, você pode escrever about://memory na barra de endereço.

A seção Summary mostra o uso total de memória de todos os processos do Chrome.

    
por 28.03.2015 / 19:27
0

Um tempo atrás eu escrevi um ótimo (e talvez um pouco feio) arquivo em lote que faz isso, ele requer sed e cut do gnuwin32.

Eu escrevi porque fiquei horrorizado com a quantidade de RAM que os navegadores modernos ocupam e eu queria ver rapidamente.

No momento, estou tentando organizá-lo, mas é assim.

Então, está dizendo que o Chrome está usando 3,4 GB

    C:\>ramchrome<ENTER>
    >=1GB
    3GB
    3,480,288
    3.4GB (rounded down)
    3480288KB

Aqui está o arquivo em lote. Houve uma época muito mais simples. Mas eu queria adicionar, por exemplo GB e KB .. e que ocupa a maior parte do arquivo de lote. É uma prova muito futura porque, mesmo que o Chrome tenha usado muitos yottabytes (um yottabyte é um milhão de trilhões de megabytes), meu lote deve ou, pelo menos, está escrito para suportar isso.

A base de como os componentes internos do arquivo de lote funciona é simples. Ele cria alguns arquivos temporários ... que você pode ver. Você vê que basicamente exibe uma lista de todos os processos, filtra os de cromo .exe agarra apenas a parte que indica quantos bytes ele usa. Em seguida, o último arquivo temporário que você pode gerar verá que apenas tem uma lista de todos os bytes usados por cada processo chrome.exe, com quaisquer vírgulas ou espaços removidos e, em seguida, uma instrução for soma todos eles. O último arquivo temporário pode ser aberto no excel .. embora não seja necessário.

Você vê como usar o arquivo bat, basta executá-lo e ver o que é gerado. Você não precisa saber como funciona, mas é assim que funciona. Você vê de olhar para os arquivos temporários que gera.

@echo off
setlocal enableextensions enabledelayedexpansion


set tempfile1=%temp%\asdf1.a
set tempfile2=%temp%\asdf2.a
set tempfile3=%temp%\asdf3.a
set tempfile4=%temp%\asdf4.xls

tasklist >%tempfile1%
type %tempfile1% | grep "chrome" > %tempfile2%
cut -b 68- %tempfile2% > %tempfile3%
sed -r "s/\d32|K|,//g" %tempfile3% >%tempfile4%


set total=0
for /f %%f in (%tempfile4%) do @(set /a total+=%%f)>nul

:: --- added this
set a=%total%

if "%a:~-9,-6%"=="" echo ^< 1GB
if NOT "%a:~-13,-6%"=="" echo ^>=1GB

set yotta=%a:~-24,-21%
set zetta=%a:~-21,-18%
set exa=%a:~-18,-15%
set peta=%a:~-15,-12%
set tera=%a:~-12,-9%
set giga=%a:~-9,-6%
set mega=%a:~-6,-3%
set kilo=%a:~-3%

set prefix=

if NOT "!yotta!"=="" (
    set yotta=!yotta!,
    if "!prefix!"=="" (
        set prefix=YB
        echo !a:~-24,-21!!prefix!
    )
)

if NOT "!zetta!"=="" (
    set zetta=!zetta!,
    if "!prefix!"=="" (
      set prefix=ZB
      echo !a:~-21,-18!!prefix!
    )
)

if NOT "!exa!"=="" (
    set exa=!exa!,
    if "!prefix!"=="" (
      set prefix=EB
      echo !a:~-18,-15!!prefix!
    )
)

if NOT "!peta!"=="" (
    set peta=!peta!,
    if "!prefix!"=="" (
      set prefix=PB
      echo !a:~-15,-12!!prefix!
    )
)

if NOT "!tera!"=="" (
    set tera=!tera!,
    if "!prefix!"=="" (
      set prefix=TB
      echo !a:~-12,-9!!prefix!
    )
)

if NOT "!giga!"==""  (
    set giga=!giga!,
    if "!prefix!"=="" (
      set prefix=GB
      echo !a:~-9,-6!!prefix!
    )
)

if NOT "!mega!"==""  (
    set mega=!mega!,
    if "!prefix!"=="" (
      set prefix=MB
      echo !a:~-6,-3!!prefix!
    )
)

if "!mega!"=="" (
  if "!prefix!"=="" (
   set prefix=KB
   echo !kilo!
  )
)


echo !yotta!!zetta!!exa!!peta!!tera!!giga!!mega!!kilo!

if "%prefix%"=="YB" echo !a:~-24,-21!.!a:~-21!YB (rounded down)
if "%prefix%"=="TB" echo !a:~-12,-9!.!a:~-9,1!TB  (rounded down)
if "%prefix%"=="GB" echo !a:~-9,-6!.!a:~-6,1!GB (rounded down)
if "%prefix%"=="MB" echo !a:~-6,-3!.!a:~-3,1!MB (rounded down)


:: echo %a:~-13,-6%,%a:~-6,-3%,%a:~-3%
 set a=
:: -----------

echo %total%KB
set tempfile1=
set tempfile2=
set tempfile3=
set tempfile4=

Para resumir como funciona, aqui está uma amostra do primeiro arquivo temporário asdf1.a, como você pode ver, ele lista muitos processos, não apenas chrome.exe

chrome.exe                    5572 Console                    1     64,784 K
chrome.exe                    3880 Console                    1    155,376 K
chrome.exe                   14516 Console                    1    106,932 K
chrome.exe                    2524 Console                    1     88,464 K
dllhost.exe                  15996 Console                    1      8,844 K
tasklist.exe                 16232 Console                    1      7,152 K

O segundo arquivo temporário se aproxima do que desejamos, filtrando o chrome.exe

asdf2.a

chrome.exe                    5572 Console                    1     64,784 K
chrome.exe                    3880 Console                    1    155,376 K
chrome.exe                   14516 Console                    1    106,932 K
chrome.exe                    2524 Console                    1     88,464 K

asdf3.a se aproxima ainda

 64,784 K
155,376 K
106,932 K
 88,464 K

asdf4.xml (não pergunte por que é .xls talvez eu pretendesse abri-lo no excel)

64796
155592
114084
88464

Então, o arquivo em lote gerou uma lista simples para somar.

e, obviamente, esta linha do arquivo de lote faz a soma

for /f %%f in (%tempfile4%) do @(set /a total+=%%f)>nul

Nota O uso de um arquivo em lote para escrever isso foi bobo .. Os arquivos em lote muitas vezes não são muito portáteis porque uma pequena alteração na saída de um comando com uma nova versão do sistema operacional ou uma nova versão de um comando, pode fazer o programa não funcionar. E se depender de programas de terceiros, onde diferentes versões deles estão lá fora, não é bom. E muitos dos comandos do gnuwin32 estão desatualizados, o cygwin tende a ser mais atualizado com suas versões de comandos. Isso estava funcionando bem para mim, embora agora eu tentei isso deu um erro.

Eu poderia escrever algo em C # em algum momento.

Observe também que, como Rick apontou, isso não leva em conta as DLLs usadas por um programa. Embora pessoalmente eu encontre o que é útil para mim é saber o quanto é usado pelo executável (ou, no caso de alguns navegadores modernos, as muitas instâncias do executável!)

    
por 28.03.2015 / 22:28