Pergunta

Nossa aplicação está a falhar no computador de um usuário específico com ERROR_NOT_ENOUGH_MEMORY ( "Não existe memória suficiente para processar este comando").

O erro é aparentemente sendo levantada em algum lugar profundo no âmbito Delphi VCL que estamos usando, então eu não tenho certeza de qual função API do Windows é responsável.

é a memória um problema? Uma chamada para GlobalMemoryStatus dá as seguintes informações:

  • dwTotalPhys - 1063150000 (~ 1 GB)
  • dwAvailPhys - 26735000 (~ 27 MB)
  • dwAvailPage - 1489000000 (~ 1,4 GB)

Parece-me estranho que o Windows iria deixar a memória física disponível obtenha baixo quando tanto espaço está disponível no arquivo de paginação, mas eu não sei o suficiente sobre o gerenciamento de memória virtual do Windows' para saber se isso é normal ou não. É?

Se não há memória, em seguida, que limite de recursos está sendo atingido? Pelo que eu li online, ERROR_NOT_ENOUGH_MEMORY poderia ser o resultado da aplicação de bater qualquer um dos vários limites (GDI objetos, objetos de usuário, punhos, etc.) e não necessariamente memória. Existe uma lista abrangente do que limita Enforces Windows? Existe alguma maneira de descobrir que limite está sendo atingido? Eu tentei Google, mas eu não poderia encontrar qualquer visão sistemática.

Foi útil?

Solução 3

O culpado neste caso foi CreateCompatibleBitmap . Aparentemente, o Windows pode impor limites de todo o sistema muito estritas para a memória disponível para bitmaps dependentes do dispositivo (ver, por exemplo, esta mailing list discussão ), mesmo se o seu sistema de outra forma tem muita memória e abundância de recursos GDI. (Esses limites em todo o sistema são aparentemente porque o Windows pode alocar bitmaps dependentes de dispositivos na memória da placa de vídeo.)

A solução é simplesmente usar bitmaps independentes de dispositivo (DIBs) em vez (embora estes não podem oferecer tão bom de um desempenho). Este artigo KB descreve como escolher o formato ideal DIB para um dispositivo.

Outros candidatos para limites de recursos (de respostas dos outros e minha própria pesquisa):

  • recursos GDI (de esta resposta) - facilmente verificados com GDIView
  • fragmentação de memória virtual (a partir desta resposta)
  • Desktop Heap - veja aqui ou aqui

Outras dicas

Verifique todas as possibilidades.

GDI-problemas pode ser monitorado usando o utilitário gratuito GDIView . É um único arquivo que os usuários podem começar sem um instalador.

Além disso, instale o ProcessExplorer na máquina em questão.

Se você não tem acesso à máquina, pedir que o usuário faça screenshots do estado monitorado pelas aplicações. Muito likeley, isso vai lhe dar alguma dica.

A causa mais comum deste erro do que qualquer daqueles que você listou é a fragmentação de memória virtual. Esta situação a que, enquanto a memória livre total é bastante razoável o espaço livre é fragmentado com vários bits de espaço de memória virtual que está sendo actualmente afectados. Daí você pode obter um erro de falta de memória quando um pedido de memória não pode ser satisfeita por um único bloco contíguo apesar da bastando no total livre.

A minha resposta pode ser um pouco tarde, mas, do meu tarde experiência com essa mesma questão, fazendo todos os testes, indo passo a passo, a criação de DC, liberá-lo, usando DIBSection vez de CompatibleBitmap, utilizando ferramentas vazamento GDI / Memória , etc.

No final (LOL) eu descobri que:

Eu estava mudando a prioridade destas duas chamadas, em seguida, todo o problema foi corrigido.

DeleteDC(hdc);       //do it first (always before deleting objects)
DeleteObject(obj);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top