Exceção de falta de memória do .NET - usado 1,3 GB, mas tem 16 GB instalados

91

Estou recebendo uma exceção de falta de memória em meu aplicativo c # quando o uso de memória para o aplicativo ultrapassa cerca de 1,3 GB.

Eu tive esse mesmo problema em uma máquina de 32 bits com 3 gb de memória e fazia sentido naquela época, mas agora eu atualizei o hardware para uma máquina de 64 bits com memória de 16 GB com placa-mãe topo de linha e RAM, mas sem memória a exceção ainda ocorre após 1,3 GB!

Eu sei que não há objetos únicos acima de 2 GB e 1.3 é menos que 2 GB de qualquer maneira, então o limite embutido de 2 GB do MS em um único objeto provavelmente não será o problema ...

Parece que há algum tipo de chave de eliminação do Windows quando um aplicativo atinge um certo limite de uso de memória ... Então, deve haver uma maneira de configurar isso no registro, talvez?

Qualquer ajuda será muito apreciada!

Paceman
fonte
9
O seu sistema operacional também é de 64 bits?
fge
9
Mesmo se o seu sistema operacional for de 64 bits, certifique-se de que seu processo também seja de 64 bits (ou AnyCPU)
Knowleech

Respostas:

90

Não há diferença até que você compile para a mesma arquitetura de destino. Eu suponho que você está compilando para 32arquitetura bit em ambos os casos.

Vale a pena mencionar que OutOfMemoryExceptiontambém pode ser aumentado se você obtiver 2GBmemória alocada por uma única coleção no CLR (digamos List<T>) em ambas as arquiteturas 32e 64bit.

Para poder se beneficiar das vantagens da memória na 64arquitetura de bits, você deve compilar sua 64arquitetura de bits de segmentação de código . Depois disso, naturalmente, seu binário rodará apenas em 64bits, mas se beneficiará da possibilidade de ter mais espaço disponível na RAM.

Tigran
fonte
8
E sobre AnyCPU?
dtb
1
Sim, AnyCPU também é uma opção, onde você tem a opção de código dependente da arquitetura JIT. Mas almejar uma arquitetura específica ainda pode se beneficiar, nos casos em que você tem recursos não gerenciados (digamos). Não tenho ideia do que é a arquitetura do OP.
Tigran
4
Eu sabia disso :) - Obrigado Tigran, reconstruí a solução em x64 e a exceção foi embora.
Paceman
63

Como já mencionado, compilar o aplicativo em x64 oferece muito mais memória disponível.

Mas no caso de ser necessário construir um aplicativo em x86, há uma maneira de aumentar o limite de memória de 1,2 GB para 4 GB (que é o limite real para processos de 32 bits):

Na pasta VC / bin do diretório de instalação do Visual Studio, deve haver um editbin.exearquivo. Então, na minha instalação padrão, eu o encontro em

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\editbin.exe

Para fazer o programa funcionar, talvez você deva primeiro executar vcvars32.batno mesmo diretório. Então uma

editbin /LARGEADDRESSAWARE <your compiled exe file>

é o suficiente para permitir que seu programa use 4 GB de RAM. <your compiled exe file>é o exe, que o VS gerou durante a compilação do seu projeto.

Se você deseja automatizar esse comportamento sempre que compilar seu projeto, use o seguinte evento Pós-construção para o projeto executado:

if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
   call "$(DevEnvDir)..\tools\vsvars32.bat"
   editbin /largeaddressaware "$(TargetPath)"
)

Nota lateral: O mesmo pode ser feito com o devenv.exepara permitir que o Visual Studio também use 4 GB de RAM em vez de 1,2 GB (mas primeiro faça backup do antigo devenv.exe).

Desty
fonte
Muito obrigado. Isso funciona para mim. Mas temos algum problema identificado após aumentar o limite de memória para 4 GB.
Maverick de
28

Vale a pena mencionar que o padrão para uma compilação de 'Qualquer CPU' agora marca a caixa de seleção 'Preferir 32 bits'. Sendo definido como AnyCPU, em um sistema operacional de 64 bits com 16 gb de RAM ainda pode atingir uma exceção de falta de memória a 2 gb se estiver marcada.

Prefer32BitCheckBox

Tonycoupland
fonte
2
Isso resolveu absolutamente meus problemas de falta de memória e nos salvou de
muita
2

Parece que você tem um arco de 64 bits, tudo bem - mas uma versão de 32 bits do runtime .NET e / ou uma versão de 32 bits do Windows.

E, como tal, o espaço de endereço disponível para o seu processo ainda é o mesmo, ele não mudou em relação à configuração anterior.

Faça upgrade para um sistema operacional de 64 bits e uma versão .NET de 64 bits;)

fge
fonte
1

Seu aplicativo está sendo executado como um processo de 64 ou 32 bits? Você pode verificar isso no gerenciador de tarefas.

Pode ser que esteja rodando em 32 bits, embora todo o sistema esteja rodando em 64 bits.

Se 32 bits, uma biblioteca de terceiros pode estar causando isso. Mas primeiro certifique-se de que seu aplicativo está compilando para "Qualquer CPU", conforme declarado nos comentários.

Jacco
fonte
0

Se você tiver o Windows de 32 bits, esse método não funcionará sem as configurações a seguir.

  1. Execute o prompt cmd.exe (importante: Executar como administrador)
  2. digite bcdedit.exe e execute
  3. Olhe para os parâmetros "boostuserva" e não há, então, escreva a seguinte declaração
  4. bcdedit / set boostuserva 3072
  5. e novamente a etapa 2 e verifique os parâmetros

Nós adicionamos essas configurações e este bloqueio começou.

if exist "$(DevEnvDir)..\tools\vsvars32.bat" (
   call "$(DevEnvDir)..\tools\vsvars32.bat"
   editbin /largeaddressaware "$(TargetPath)"
)

Mais informações - comando increaseuserva: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/bcdedit--set

Mehmet Kurt
fonte