Pergunta

Eu estou tentando descobrir o quanto de memória o meu próprio .Líquido de processo do servidor está usando (para monitoramento e fins de registo).

Eu estou usando:

Process.GetCurrentProcess().PrivateMemorySize64

No entanto, o objeto de Processo tem várias propriedades diferentes que gostaria de ler o espaço de memória utilizado:Paginada, Não Paginado, PagedSystem, NonPagedSystem, Privadas, Virtual, WorkingSet

e, em seguida, os "picos":que eu estou supondo que apenas armazenar os valores máximos, estes últimos já levou.

Por meio da leitura do MSDN definição de cada propriedade ainda não provou ser muito útil para mim.Eu tenho que admitir meu conhecimento a respeito de como a memória é gerenciada (na medida do paginação virtual e vai) é muito limitado.

Então a minha pergunta é, obviamente, "o que eu devo usar?", e eu sei que a resposta é "depende".

Este processo será, basicamente, conter um monte de listas na memória das coisas que estão acontecendo, enquanto outros processos de comunicar-se com ele e consultá-lo para outras coisas.Eu estou esperando o servidor onde este será executado em exigir muita memória RAM, e por isso estou consultando dados ao longo do tempo, para ser capaz de estimar os requisitos de RAM quando comparado com os tamanhos das listas mantém dentro.

Então...O que eu devo usar e por quê?

Foi útil?

Solução

Se você quiser saber o quanto o GC usa tentar:

GC.GetTotalMemory(true)

Se você quer saber o que o processo usa a partir do Windows (VM Tamanho coluna no TaskManager) tentar:

Process.GetCurrentProcess().PrivateMemorySize64

Se você quer saber o que o seu processo tem na memória RAM (ao contrário no arquivo de paginação) (coluna de Uso de memória no TaskManager) tentar:

Process.GetCurrentProcess().WorkingSet64

Ver aqui para mais explicações sobre os diferentes tipos de memória.

Outras dicas

OK, eu descobri através do Google mesma página que Lars mencionados, e eu acredito que é uma grande explicação para as pessoas que não sabem bem como funciona a memória (como eu).

http://shsc.info/WindowsMemoryManagement

Minha breve conclusão foi:

  • Private Bytes = A Memória de meu processo pediu para armazenar dados.Algumas delas podem ser paginadas para o disco ou não.Esta é a informação que eu estava procurando.

  • Virtual Bytes = Bytes Privados, além de o espaço compartilhado com outros processos de DLLs carregadas, etc.

  • Conjunto de trabalho = A parte de TODA a memória do meu processo que não foi paginada para o disco.Por isso, a quantidade de bloco paginado para o disco deve ser (Virtual - Conjunto de Trabalho).

Obrigado a todos pela vossa ajuda!

Se você deseja usar a "Memória (Conjunto de Trabalho Privado)", conforme mostrado no gerenciador de tarefas do Windows Vista, que é o equivalente do Process Explorer "WS Bytes Privados", aqui está o código.Provavelmente o melhor para lançar este loop infinito em um thread/tarefa de plano de fundo para estatísticas em tempo real.

using System.Threading;
using System.Diagnostics;

//namespace...class...method

Process thisProc = Process.GetCurrentProcess();
PerformanceCounter PC = new PerformanceCounter();

PC.CategoryName = "Process";
PC.CounterName = "Working Set - Private";
PC.InstanceName = thisProc.ProcessName;

while (true)
{
 String privMemory = (PC.NextValue()/1000).ToString()+"KB (Private Bytes)";
 //Do something with string privMemory

 Thread.Sleep(1000);
}

Para obter o valor que o Gerenciador de Tarefas dá, eu tiro o meu chapéu para Mike Regan da solução acima.No entanto, uma mudança:ele não é: perfCounter.NextValue()/1000; mas perfCounter.NextValue()/1024; (i.é.um verdadeiro kilobytes).Isso dá o valor exato que você ver no Gerenciador de Tarefas.

A seguir é uma solução completa para apresentar a "memória de uso' (gerenciador de Tarefas, como dado) de uma forma simples em seu WPF ou WinForms aplicativo (neste caso, apenas o título).Apenas chamar este método dentro da nova Janela construtor:

    private void DisplayMemoryUsageInTitleAsync()
    {
        origWindowTitle = this.Title; // set WinForms or WPF Window Title to field
        BackgroundWorker wrkr = new BackgroundWorker();
        wrkr.WorkerReportsProgress = true;

        wrkr.DoWork += (object sender, DoWorkEventArgs e) => {
            Process currProcess = Process.GetCurrentProcess();
            PerformanceCounter perfCntr = new PerformanceCounter();
            perfCntr.CategoryName = "Process";
            perfCntr.CounterName = "Working Set - Private";
            perfCntr.InstanceName = currProcess.ProcessName;

            while (true)
            {
                int value = (int)perfCntr.NextValue() / 1024;
                string privateMemoryStr = value.ToString("n0") + "KB [Private Bytes]";
                wrkr.ReportProgress(0, privateMemoryStr);
                Thread.Sleep(1000);
            }
        };

        wrkr.ProgressChanged += (object sender, ProgressChangedEventArgs e) => {
            string val = e.UserState as string;
            if (!string.IsNullOrEmpty(val))
                this.Title = string.Format(@"{0}   ({1})", origWindowTitle, val);
        };

        wrkr.RunWorkerAsync();
    }`

Conjunto de trabalho não é uma boa propriedade para usar.Pelo que eu sei, ele inclui tudo o que o processo pode tocar, até mesmo bibliotecas compartilhadas por vários processos, portanto, você está vendo casal contados de bytes no contador.Privados de memória é muito melhor contador para olhar.

Eu sugiro também o monitor de frequência pagefaults acontecer.Um pagefault acontece quando você tenta acessar alguns dados que foram movidos da memória física para o ficheiro swap do sistema e tem a página de leitura de disco antes de poder acessar esses dados.

Esta é uma justa descrição?Eu gostaria de compartilhar isso com a minha equipe, então por favor deixe-me saber se é incorreta (ou incompleta):

Existem várias maneiras em C# para perguntar o quanto de memória o meu processo está usando.

  • Memória alocada pode ser gerenciado (pelo CLR) ou não gerenciado.
  • Memória alocada pode ser virtual (armazenado no disco) ou carregado (RAM páginas)
  • Memória alocada pode ser privado (usado apenas pelo processo) ou compartilhados (por exemplo,pertencentes a uma DLL que outros processos estão de referência).

Dado o acima, aqui estão algumas maneiras para medir o uso de memória em C#:

1) Processo.VirtualMemorySize64():devolve toda a memória usada por um processo gerenciado ou não gerenciado, virtual ou carregado, privadas ou compartilhadas.

2) Processo.PrivateMemorySize64():retorna todas as privadas de memória utilizada por um processo gerenciado ou não gerenciado, virtual ou carregado.

3) do Processo.WorkingSet64():retorna todos os particulares, carregado de memória utilizada por um processo gerenciado ou não gerenciado

4) GC.GetTotalMemory():retorna a quantidade de memória gerenciada a ser observado pelo coletor de lixo.

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