Je me demande pourquoi je ne suis pas en mesure d’allouer plus de 1 000 Mo de mémoire dans mon processus .NET 32 bits. La mini-application suivante lève une exception OutOfMemoryException après avoir alloué 1 000 Mo. Pourquoi 1 000 Mo, et non pas 1,8 Go? Y at-il un paramètre de processus que je pourrais changer?
static void Main(ssortingng[] args) { ArrayList list = new ArrayList(); int i = 0; while (true) { list.Add(new byte[1024 * 1024 * 10]); // 10 MB i += 10; Console.WriteLine(i); } }
PS: La collecte des ordures n’aide pas.
Éditer, pour clarifier ce que je veux: j’ai écrit une application serveur qui traite de très grandes quantités de données avant d’écrire dans la firebase database / le disque. Au lieu de créer des fichiers temporaires pour tout, j’ai écrit un cache en mémoire, ce qui rend le tout très rapide. Mais la mémoire est limitée et j’ai donc essayé de connaître les limites. Et je me suis demandé pourquoi mon petit programme de test lançait l’exception OutOfMemoryException après exactement 1 000 Mo.
La limite d’espace d’adressage virtuel d’un processus Win32 est de 1,5 Go (pas tout à fait vrai). De plus, les frameworks .NET limitent le pourcentage de mémoire qu’un processus .NET peut consumr. Machine.config a un élément processModel avec un atsortingbut memoryLimit qui correspond au% de mémoire disponible qu’un processus peut consumr. La valeur par défaut est 60%.
Si la machine sur laquelle vous travaillez est équipée de 2 Go de mémoire ou si vous n’avez pas activé le commutateur / 3GB dans votre fichier Boot.ini, vous obtiendrez environ 1,3 Go de mémoire par processus.
Je ne trouve pas l’article de la Base de connaissances, mais si je me souviens bien, .NET 1.x ne peut pas traiter au-delà de la limite de 1,5 Go (1,8 Go?), Quels que soient vos parameters.
http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx http://social.msdn.microsoft.com / Forums / fr-fr / clr / thread / c50ea343-b41b-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_-_Caching#Configure_the_Memory_Limit
Avoir d’énormes blocs de mémoire n’est jamais une bonne idée, même en 64 bits. Vous avez de gros problèmes de mémoire contiguë et de fragmentation.
Le problème ici est de trouver un bloc contigu. Vous pouvez essayer d’activer le mode 3 Go (ce qui pourrait l’aider à trouver quelques octets de plus), mais je le déconseille vraiment . Les réponses ici sont:
Vous voudrez peut-être aussi lire le blog d’ Eric Lippert (il semble avoir une entrée de blog pour chaque question .NET commune …)
J’ai récemment effectué un profilage approfondi autour des limites de mémoire dans .NET sur un processus 32 bits. Nous sums tous bombardés par l’idée que nous pouvons allouer jusqu’à 2,4 Go (2 ^ 31) dans une application .NET mais, malheureusement, ce n’est pas vrai :(. Le processus de demande a autant d’espace à utiliser et le système Cependant, .NET lui-même semble avoir sa propre surcharge, ce qui représente environ 600 à 800 Mo d’applications typiques du monde réel qui repoussent les limites de la mémoire. Cela signifie que dès que vous allouez un tableau d’entiers prenant environ 1,4 Go, vous devriez vous attendre à voir une OutOfMemoryException ().
Évidemment, en 64 bits, cette limite survient bien plus tard (discutons dans 5 ans :)), mais la taille générale de tout ce qui est en mémoire augmente également (je trouve que c’est ~ 1,7 à ~ 2 fois) en raison de la taille accrue du mot.
Ce que je sais avec certitude, c’est que l’idée de mémoire virtuelle du système d’exploitation ne vous donne PAS un espace d’allocation pratiquement infini au sein d’un même processus. Ce n’est que là-bas que la totalité des 2,4 Go est adressable à toutes les applications (nombreuses) exécutées en même temps.
J’espère que cette idée aide un peu.
A l’origine, j’ai répondu à quelque chose de ce qui est raconté ici (je suis toujours un nouveau-né, donc je ne sais pas comment je suis censé faire ces liens):
Existe-t-il une limite de mémoire pour un seul processus .NET?
Vous pouvez allouer BEAUCOUP PLUS de mémoire que ~ 2 Go en générant votre application à une architecture 64 bits, ce qui nécessite la création d’une nouvelle configuration de construction dans Visual Studio, et cette version de l’application ne sera exécutée que sur les versions 64 bits de Windows. . Dans .NET, avec l’option de construction par défaut “N’importe quel processeur” pour votre application, je constate que je ne peux allouer que 1,5 Go de mémoire à partir du segment de mémoire (même sur une machine Windows 64 bits). ne fonctionne en mode 32 bits que s’il est construit en mode “Tout processeur”. Mais en compilant une architecture x64, vous pouvez allouer beaucoup, beaucoup plus de mémoire du tas pendant l’exécution de votre application, et j’expliquerai comment créer une construction x64 pour votre application ci-dessous:
Là encore, en utilisant l’option de construction “Tous les processeurs” normale (par défaut) de votre projet .NET, votre application sera TOUJOURS exécutée en mode 32 bits, même sur un système d’exploitation Windows 64 bits. Par conséquent, vous ne pourrez pas allouer plus de 1,5 à 2 Go de mémoire RAM pendant l’exécution de l’application. Pour exécuter votre application .NET en véritable mode 64 bits, vous devez accéder au gestionnaire de configuration de génération, créer un type de construction pour l’architecture x64, puis recomstackr votre programme pour x64 de manière explicite à l’aide de ce type de construction. L’option de mode de construction x64 peut être créée pour votre solution .NET en procédant comme suit:
L’utilisation d’une version 64 bits de votre application sur un système d’exploitation Windows 64 bits permettra à votre programme d’allouer bien plus que ~ 2 Go de mémoire, probablement jusqu’à 2 ^ 64 espaces d’adressage (si vous disposez de la RAM et de l’espace disque disponibles). sont les véritables facteurs limitants au moment de la rédaction de cette réponse).
Si vous manquez ENCORE de mémoire dans votre application, vous pouvez également augmenter la taille du fichier de page mémoire Windows. Sous Windows, le fichier d’échange permet au système d’exploitation de déplacer la mémoire de la RAM vers le disque s’il manque d’espace de mémoire RAM. Toutefois, le déplacement de parties de la mémoire RAM vers et depuis le disque représente un coût important en temps, de sorte que les performances de votre application peuvent en souffrir. Quelles que soient les performances, en augmentant la taille de la page, vous pourriez (en théorie) agrandir le fichier de page, car il y a de la place disponible sur le lecteur C: de votre ordinateur Windows. Dans ce cas, votre application pourrait allouer, par exemple, jusqu’à 4 To de mémoire (ou la quantité de mémoire définie pour la taille de votre fichier de page) pendant l’exécution de votre programme. Pour modifier les parameters de fichier de page pour votre ordinateur Windows, procédez comme suit:
Quoi qu’il en soit, j’espère que cela aidera les gens à comprendre pourquoi ils peuvent rencontrer ce problème de limitation de mémoire de 1,5 à 2 Go dans une application .NET, même sur une machine Windows 64 bits. Cela peut être une question très déroutante pour les gens et j’espère que mon explication est logique. S’il vous plaît n’hésitez pas à m’envoyer un message avec des questions sur cette réponse si nécessaire.
Je pense que le problème ici est que cette application appenda 10 Mo à chaque boucle qu’elle crée, et la boucle est: “while (true)”, ce qui signifie qu’elle appenda ces 10 Mo jusqu’à ce que l’application soit arrêtée. Donc, si cela fonctionnait pendant 100 boucles, cela aurait ajouté près de 1 Go à la RAM, et je suppose que cela aurait été fait en moins de 30 secondes. Mon point est que vous essayez de 10 mégaoctets de mémoire par boucle, dans une boucle sans fin
Je suis vraiment désolé si je n’ai pas compris votre point mais:
static void Main(ssortingng[] args) { ArrayList list = new ArrayList(); int i = 0; while (true) { using(byte newBt = new byte[1024 * 1024 * 10]) { list.Add(newBt); // 10 MB i += 10; Console.WriteLine(i); } } }
Avez-vous essayé la méthode d’utilisation? Et cela pourrait être une question stupide mais pourquoi avez-vous créé une boucle éternelle? O si vous essayez la bande de code, les symboles>.> XD.
Source: http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx