Pergunta

Existe uma API .NET para obter informações detalhadas sobre o uso da VM? Estou especificamente interessado em determinar o quão fragmentado é o meu espaço de endereço.

Obrigado!

Foi útil?

Solução

Os tipos de funções da API do Windows que podem fornecer algumas dicas sobre isso são VirtualQueryEx () para enumerar as seções de memória virtual e descobrir espaço não utilizado, getProcessHeaps () para encontrar quais heaps são criados dentro do processo e heapwalk () para descobrir como os blocos entram Cada heap são usados.

Isso não será fácil, principalmente o heapwalk () é uma função problemática em um programa em execução. Você deve dar uma olhada nos sysinternals ' Utilitário vmmap, fornece excelente diagnóstico de memória virtual.

A queda com isso é que ele realmente não ajuda a resolver um problema de fragmentação da memória. Não há nada que você possa fazer para afetar a maneira como o Windows Memory Manager subloca o espaço de memória virtual. Curto de não alocar memória. Se você está lutando agora com a OOM, realmente deve considerar re-arquiteta seu aplicativo. Ou mudar para um sistema operacional de 64 bits, a solução de duzentos dólares.

Outras dicas

Resposta curta: Não. Você precisa explorar a API Win32 para isso. Eu realmente não sei o que a API chama de você usaria ...

Uma pesquisa rápida em http://www.pinvoke.net me levou a isso:

[DllImport("coredll.dll", SetLastError=true)]
static extern void GlobalMemoryStatus(ref MEMORYSTATUS lpBuffer);

Mas o MemoryStatus Struct não parece ter todas as informações necessárias (apenas uso físico e virtual da memória e outras informações).

Você deve cavar o MSDN para encontrar o método necessário.

Essa chamada não faz sentido no mundo gerenciado, pois diferentes hosts de CLR podem lidar com as coisas diferentes (como o host normal de aplicativos ou o SQL Server). E não se esqueça que o GC pode mover as coisas, para que a fragmentação não seja realmente um problema seja o GC compacta a pilha.

No entanto, isso me leva ao próximo ponto, você poderá obter essas informações hospedando o CLR você mesmo. Você pode querer olhar para Este post sobre este tópico.

Você realmente precisa entrar na API Win32/Win64 para obter essas informações no nível da página. Qualquer coisa mais detalhada e você precisa conhecer o funcionamento interno de qualquer pilha que esteja olhando, seja uma pilha C, pilha Win32, uma pilha de objetos pequenos CLR ou uma pilha de objeto grande CLR.

No entanto, você pode usar Validador de memória virtual (que é comercial, mas gratuito) para visualizar o espaço de memória virtual e também examinar a página da memória por página e parágrafo por parágrafo. Veja os visuais primeiro, pois isso facilita a ver problemas e tendências gerais. Em seguida, observe as informações detalhadas sobre páginas e parágrafos quando decidir quais áreas de memória são problemáticas.

Aqui está um artigo de blog descrevendo o que Páginas e parágrafos são.

Em C, você pode escrever algo assim para saber quanta memória é alocada:

HANDLE heap = GetProcessHeap();
PROCESS_HEAP_ENTRY entry;
memset(&entry, 0, sizeof(entry));
unsigned long size = 0;
while(HeapWalk(heap, &entry)) {
    if(entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) {
        size += entry.cbData;
    }
}

O getProcessHeaps () pode ser necessário se outros montes forem usados, nesse caso, você precisará de um segundo loop para passar por todos os montes. Não sei por que o deles seria mais de um.

No seu caso, você provavelmente deve contar o número de blocos e seus tamanhos. Se você deseja salvar isso no disco, sugiro que você conte primeiro o número de blocos, aloque um buffer para salvar todas as informações e salve o buffer em um arquivo para revisão posterior.

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