Quando um EXE ou DLL reutiliza memória 'física'?

1

Com o passar dos anos, meu aplicativo cresceu de alguns MB para mais de 50 MB. Para simplificar a implantação, sempre fiquei com um único arquivo EXE em vez de ter um EXE menor e muitas DLLs (veja também minha pergunta no StackOverflow: link ).

No entanto, agora tenho alguns clientes que reclamam que cada nova versão tem requisitos de memória mais altos. Mover para DLLs pode resolver alguns desses problemas, porque acho que o Windows carrega apenas uma vez na memória da DLL (portanto, se você tiver 50 processos usando a mesma DLL, a DLL só ocupa espaço uma vez na memória física).

Por outro lado, se eu tiver 50 processos, todos usando o mesmo arquivo EXE, eu esperaria que o Windows também compartilhe esse arquivo EXE para vários processos. Mas tenho a impressão de que o Windows não faz isso (e só faz isso para arquivos DLL). Esta observação é verdadeira?

O Windows realmente carrega uma DLL uma vez na memória se usado por vários processos?

O Windows também carrega um arquivo EXE uma vez na memória, se usado por vários processos? Ou não?

    
por Patrick 26.11.2013 / 12:40

2 respostas

2

Primeiro, observe que os métodos DLLs e as construções estáticas fazem parte do espaço ocupado pela pilha do processo e, portanto, sua memória não é alocada dinamicamente, portanto, dividir as coisas com dlls adicionais não reduzirá seus requisitos de RAM reais.

A memória do processo pode ser medida usando os Private Bytes (a ocupação total da memória do processo, menos os objetos compartilhados; pode não refletir o uso físico do RAM) bytes do conjunto de trabalho (memória física atual em uso, mais objetos compartilhados) e conjunto de trabalho privado (memória física completa em uso, sem nenhum objeto compartilhado). Tudo isso pode ser monitorado no ProcessExplorer da Sysinternal. O WS Private é provavelmente a melhor métrica para monitorar a quantidade de carga que seu programa coloca no host.

    
por 26.11.2013 / 13:55
2

O código DLL e EXE é absolutamente compartilhado - há apenas uma cópia do código na RAM, independentemente de quantos processos estão usando o EXE ou as DLLs. (E nem todo o código estará necessariamente na RAM - apenas o que foi referenciado recentemente).

DLLs e EXEs são exemplos de arquivos mapeados. Os arquivos mapeados contribuem para o espaço de endereço virtual total de um processo. Eles não contribuem para "bytes particulares" ou memória "comprometida" (mesma coisa, mas diferentes utilitários usam termos diferentes).

Os processos não possuem em si pilhas. Threads tem pilhas. (Pode-se dizer que um processo com apenas um thread tem "a" stack para esse processo, mas na verdade, a pilha é um atributo do thread, não o processo.) Mas as DLLs não são "carregadas em uma pilha de processos" ( nem na pilha de um thread para esse assunto). DLLs e EXEs são mapeados para o espaço de endereçamento virtual compartilhável - não privado - de um processo. É verdade que isso é feito para cada processo usando a DLL ou EXE, mas essas várias instâncias são para os mapeamentos de memória virtual. Como esse é um espaço de endereçamento virtual compartilhável, ainda há apenas uma cópia do código na RAM.

As pilhas de tópicos, juntamente com heaps (que são todo o processo) e armazenamento estático, também são mapeadas no processo v.a.s., mas diferentemente da memória mapeada, são privadas para cada processo.

    
por 26.08.2014 / 23:56