Eccezione memoria esaurita .NET: utilizzata da 1,3 GB ma installata da 16 GB


91

Ricevo un'eccezione di memoria insufficiente nella mia applicazione c # quando l'utilizzo della memoria per l'applicazione supera circa 1,3 GB.

Ho avuto lo stesso problema su una macchina a 32 bit con 3 GB di memoria e all'epoca aveva senso, ma ora ho aggiornato l'hardware a una macchina a 64 bit con 16 GB di memoria con la scheda madre e la RAM di fascia alta ma la memoria esaurita l'eccezione si verifica ancora dopo 1,3 GB!

So che non ci sono oggetti singoli oltre 2 GB e 1.3 è comunque meno di 2 GB, quindi il limite MS 2 GB integrato su un singolo oggetto non è probabile che sia il problema ...

Sembra che ci sia un kill-switch di Windows di qualche tipo quando un'app raggiunge una certa soglia di utilizzo della memoria ... Quindi dovrebbe esserci un modo per configurarlo nel registro forse?

Qualsiasi aiuto sarà molto apprezzato!


9
Anche il tuo sistema operativo è a 64 bit?
fge

9
Anche se il tuo sistema operativo è a 64 bit, assicurati che anche il tuo processo sia a 64 bit (o AnyCPU)
Knowleech

Risposte:


90

Non c'è differenza fino a quando non si compila sulla stessa architettura di destinazione. Io suppongo che si sta compilando per 32l'architettura po 'in entrambi i casi.

Vale la pena ricordare che OutOfMemoryExceptionpuò anche essere aumentato se si ottiene 2GBdella memoria allocata da una singola raccolta in CLR (diciamo List<T>) su entrambe le architetture 32e 64bit.

Per poter beneficiare della bontà della memoria sull'architettura 64bit, è necessario compilare il codice che mira 64all'architettura bit. Dopodiché, naturalmente, il tuo binario funzionerà solo su 64bit, ma beneficerà della possibilità di avere più spazio disponibile nella RAM.


8
Che mi dici di AnyCPU?
dtb

1
Sì, anche AnyCPU è un'opzione, dove hai un'opzione per il codice dipendente dall'architettura JIT. Ma il targeting di un'architettura specifica rimane comunque un vantaggio, nei casi in cui si hanno risorse non gestite (diciamo). Non ho idea di cosa sia l'architettura di OP.
Tigran

4
Lo sapevo :) - Grazie Tigran, ho ricostruito la soluzione in x64 e l'eccezione è andata via.
Paceman

63

Come già accennato, compilare l'app in x64 ti dà molta più memoria disponibile.

Ma nel caso in cui si debba creare un'app in x86, c'è un modo per aumentare il limite di memoria da 1,2 GB a 4 GB (che è il limite effettivo per i processi a 32 bit):

Nella cartella VC / bin della directory di installazione di Visual Studio, deve essere presente un editbin.exefile. Quindi nella mia installazione predefinita lo trovo sotto

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

Per far funzionare il programma, forse devi prima eseguire vcvars32.batnella stessa directory. Poi un

editbin /LARGEADDRESSAWARE <your compiled exe file>

è sufficiente per consentire al programma di utilizzare 4 GB di RAM. <your compiled exe file>è l'exe, che VS ha generato durante la compilazione del progetto.

Se vuoi automatizzare questo comportamento ogni volta che compili il tuo progetto, usa il seguente evento Post-Build per il progetto eseguito:

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

Nota a margine: lo stesso può essere fatto con il devenv.exeper consentire a Visual Studio di utilizzare anche 4 GB di RAM invece di 1,2 GB (ma prima eseguire il backup del vecchio devenv.exe).


Molte grazie. Questo funziona per me. Ma abbiamo problemi identificati dopo aver aumentato il limite di memoria a 4 GB.
Maverick,

28

Vale la pena ricordare che l'impostazione predefinita per una compilazione "Qualsiasi CPU" ora seleziona la casella di controllo "Preferisci 32 bit". Essendo impostato su AnyCPU, su un sistema operativo a 64 bit con 16 GB di RAM può ancora colpire un'eccezione di memoria insufficiente a 2 GB se questa è selezionata.

Prefer32BitCheckBox


2
Questo ha assolutamente risolto i miei problemi di memoria e ci ha risparmiato un sacco di frustrazione
RSSM

2

Sembra che tu abbia un arco a 64 bit, bene, ma una versione a 32 bit del runtime .NET e / o una versione a 32 bit di Windows.

E come tale, lo spazio degli indirizzi disponibile per il tuo processo è sempre lo stesso, non è cambiato rispetto alla configurazione precedente.

Aggiorna sia a un sistema operativo a 64 bit che a una versione .NET a 64 bit;)


1

La tua applicazione funziona come un processo a 64 o 32 bit? Puoi verificarlo nel task manager.

Potrebbe essere che funzioni a 32 bit, anche se l'intero sistema funziona a 64 bit.

Se è a 32 bit, la causa potrebbe essere una libreria di terze parti. Ma prima assicurati che la tua applicazione stia compilando per "Any CPU", come indicato nei commenti.


0

Se hai Windows a 32 bit, questo metodo non funziona senza le seguenti impostazioni.

  1. Esegui prompt cmd.exe (importante: Esegui come amministratore)
  2. digita bcdedit.exe ed esegui
  3. Guarda i parametri "aumentauserva" e non c'è quindi la seguente dichiarazione
  4. bcdedit / set aumentauserva 3072
  5. e di nuovo il passaggio 2 e controllare i parametri

Abbiamo aggiunto queste impostazioni e questo blocco è iniziato.

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

Maggiori informazioni - comando increaseuserva: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/bcdedit--set

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.