Exception de mémoire insuffisante .NET - 1,3 Go utilisé mais 16 Go installés

91

Je reçois une exception de mémoire insuffisante dans mon application c # lorsque l'utilisation de la mémoire pour l'application dépasse environ 1,3 Go.

J'ai eu ce même problème sur une machine 32 bits avec 3 Go de mémoire et cela avait du sens à l'époque, mais maintenant j'ai mis à niveau le matériel vers une machine 64 bits avec 16 Go de mémoire avec la carte mère haut de gamme et la RAM mais le Out Of Memory l'exception se produit toujours après 1,3 Go!

Je sais qu'il n'y a pas d'objets uniques de plus de 2 Go et que 1,3 est de toute façon moins de 2 Go, donc la limite MS 2 Go intégrée sur un seul objet ne sera probablement pas le problème ...

Il semble qu'il y ait une sorte de kill-switch Windows lorsqu'une application atteint un certain seuil d'utilisation de la mémoire ... Alors il devrait y avoir un moyen de configurer cela dans le registre peut-être?

Toute aide sera fortement appréciée!

Paceman
la source
9
Votre OS 64 bits est-il également?
fge
9
Même si votre système d'exploitation est 64 bits, assurez-vous que votre processus est également 64 bits (ou AnyCPU)
Knowleech

Réponses:

90

Il n'y a aucune différence tant que vous ne compilez pas sur la même architecture cible. Je suppose que vous compilez pour l' 32architecture bit dans les deux cas.

Il convient de mentionner que cela OutOfMemoryExceptionpeut également être soulevé si vous obtenez 2GBde la mémoire allouée par une seule collection dans CLR (par exemple List<T>) sur les deux architectures 32et64 bit.

Pour pouvoir bénéficier de la qualité de la mémoire sur l' 64architecture de bits, vous devez compiler votre 64architecture de bits de ciblage de code . Après cela, naturellement, votre binaire ne fonctionnera que sur 64bit, mais bénéficiera de la possibilité d'avoir plus d'espace disponible dans la RAM.

Tigran
la source
8
Qu'en est-il d'AnyCPU?
dtb
1
Oui, AnyCPU est également une option, où vous avez une option pour le code dépendant de l'architecture JIT. Mais le ciblage des restes d'architecture spécifiques peut toujours en bénéficier, dans les cas où vous avez des ressources non gérées (par exemple). Je n'ai aucune idée de ce qu'est l'architecture d'OP.
Tigran
4
Je le savais :) - Merci Tigran, j'ai reconstruit la solution en x64 et l'exception a disparu.
Paceman
63

Comme déjà mentionné, la compilation de l'application en x64 vous donne beaucoup plus de mémoire disponible.

Mais dans le cas où l'on doit créer une application en x86, il existe un moyen d'augmenter la limite de mémoire de 1,2 Go à 4 Go (qui est la limite réelle pour les processus 32 bits):

Dans le dossier VC / bin du répertoire d'installation de Visual Studio, il doit y avoir un editbin.exefichier. Donc, dans mon installation par défaut, je le trouve sous

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

Afin de faire fonctionner le programme, peut-être que vous devez d'abord l'exécuter vcvars32.batdans le même répertoire. Puis un

editbin /LARGEADDRESSAWARE <your compiled exe file>

suffit pour que votre programme utilise 4 Go de RAM. <your compiled exe file>est l'exe généré par VS lors de la compilation de votre projet.

Si vous souhaitez automatiser ce comportement chaque fois que vous compilez votre projet, utilisez l'événement Post-Build suivant pour le projet exécuté:

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

Remarque: la même chose peut être faite avec le devenv.exepour permettre à Visual Studio d'utiliser également 4 Go de RAM au lieu de 1,2 Go (mais sauvegardez d'abord l'ancien devenv.exe).

Desty
la source
Merci beaucoup. Cela fonctionne pour moi. Mais avons-nous des problèmes identifiés après avoir augmenté la limite de mémoire à 4 Go.
Maverick
28

Il convient de mentionner que la valeur par défaut pour une compilation «Any CPU» coche désormais la case «Préférer 32 bits». Étant défini sur AnyCPU, sur un système d'exploitation 64 bits avec 16 Go de RAM peut toujours frapper une exception de mémoire insuffisante à 2 Go si cela est coché.

Prefer32BitCheckBox

tonycoupland
la source
2
Cela a absolument résolu mes problèmes de mémoire et nous a évité une tonne de frustration
RSSM
2

Il semble que vous ayez une arche 64 bits, très bien - mais une version 32 bits du runtime .NET et / ou une version 32 bits de Windows.

Et en tant que tel, l'espace d'adressage disponible pour votre processus est toujours le même, il n'a pas changé par rapport à votre configuration précédente.

Mise à niveau vers un système d'exploitation 64 bits et une version .NET 64 bits;)

fge
la source
1

Votre application fonctionne-t-elle en tant que processus 64 ou 32 bits? Vous pouvez vérifier cela dans le gestionnaire de tâches.

Cela pourrait être, il fonctionne en 32 bits, même si tout le système fonctionne en 64 bits.

Si 32 bits, une bibliothèque tierce pourrait être à l'origine de ce problème. Mais assurez-vous d'abord que votre application compile pour "Any CPU", comme indiqué dans les commentaires.

Jacco
la source
0

Si vous avez Windows 32 bits, cette méthode ne fonctionne pas sans les paramètres suivants.

  1. Exécutez l'invite cmd.exe (important: Exécuter en tant qu'administrateur)
  2. tapez bcdedit.exe et exécutez
  3. Regardez les paramètres "augmenteuserva" et il n'y a pas de déclaration alors écrire suivante
  4. bcdedit / set augmenteeuserva 3072
  5. et encore l'étape 2 et vérifier les paramètres

Nous avons ajouté ces paramètres et ce bloc a commencé.

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

Plus d'infos - commande increaseuserva: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/bcdedit--set

Mehmet Kurt
la source