L'allocation de plus de 1 000 MB de mémoire de 32 bits .NET processus
Je me demande pourquoi je ne suis pas en mesure d'allouer plus de 1 000 MB de mémoire dans mon 32 bits .NET processus. La suite de la mini application déclenche une exception OutOfMemoryException après avoir attribué de 1 000 MB. Pourquoi 1 000 MO, et de ne pas dire de 1,8 GO? Est-ce qu'un processus à l'échelle de réglage, je pouvais changer?
static void Main(string[] 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.
Modifier, afin de clarifier ce que je veux: j'ai écrit une application serveur qui traite avec de très grandes quantités de données avant de les écrire dans la base/le disque. Au lieu de créer des fichiers temporaires pour tout, j'ai écrit un cache en mémoire, ce qui rend le truc super-rapide. Mais la mémoire est limitée, et donc j'ai essayé de trouver quelles sont les limites. Et je me demandais pourquoi mon petit programme de test a jeté l'exception OutOfMemoryException après exactement 1 000 MO.
Vous devez vous connecter pour publier un commentaire.
L'espace d'adressage virtuel limite d'un processus Win32 est de 1,5 GO (pas tout à fait vrai). En outre dans le .NET cadres il y a un limiteur de à la % de mémoire .NET processus peut consommer. La machine.config a un processModel élément avec un attribut memoryLimit qui est le % de la mémoire disponible un processus peut consommer. La valeur par défaut est de 60%.
Si la machine que vous utilisez dispose de 2 go de mémoire ou que vous n'avez pas activé le commutateur /3GB dans la séquence de DÉMARRAGE.INI, alors vous allez obtenir ~1,3 GO de mémoire par processus.
Je ne trouve pas l'article de base de connaissances mais si je me souviens bien .NET 1.x ne peut pas d'adresse au-delà de 1,5 GO (1,8 GO?) limite indépendamment de vos paramètres.
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/en-US/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 obtenez de gros problèmes avec la mémoire contiguë et de la fragmentation.
Le problème ici est de trouver un bloc contigu. Vous pourriez essayer de l'activer 3 go de mode (ce qui pourrait l'aider à trouver un peu plus d'octets), mais je vraiment vous le conseille. Les réponses sont ici:
Vous pouvez également lire Eric Lippert est blog (il semble avoir une entrée de blog pour chaque commune .NET question...)
J'ai récemment fait une vaste profilage de la mémoire des limites .NET sur un processus 32 bits. Nous sommes tous bombardés par l'idée que l'on peut attribuer jusqu'à 2,4 GO (2^31) dans une .NET application, mais malheureusement ce n'est pas vrai :(. Le processus de demande a beaucoup d'espace à utiliser et le système d'exploitation fait un excellent travail à gérer pour nous, cependant .NET lui-même semble avoir ses propres frais généraux, qui représente environ 600-800 MO pour les applications du monde réel que de pousser la limite de la mémoire. Cela signifie que dès que vous allouer un tableau d'entiers qui prend environ 1,4 GO, vous devriez vous attendre à voir une OutOfMemoryException().
Évidemment, en 64 bits, cette limite se produit plus tard (let's chat en 5 ans :)), mais la taille de tout dans la mémoire pousse aussi (je viens de trouver c'est ~1,7 à ~2 fois) en raison de l'augmentation de la taille de mot.
Ce que je sais, c'est que la Mémoire Virtuelle idée du système d'exploitation certainement ne vous donne PAS pratiquement infinie de l'allocation de l'espace au sein d'un processus. C'est seulement là pour que la totalité de 2,4 GO est adressable à toutes les (nombreuses) demandes d'exécution à la fois.
J'espère que cette idée vous aide un peu.
L'origine, j'avais répondu quelque chose en lien ici (je suis encore un newby ne suis pas sûr de savoir comment je suis censé faire ces liens):
Est-il une limite de mémoire pour un seul .NET processus
Vous pouvez allouer BEAUCOUP PLUS de mémoire qu' ~2 GO par la construction de votre demande pour une architecture 64 bits, ce qui nécessite la création d'une nouvelle configuration de build dans Visual Studio, et que la version de l'application va s'exécuter uniquement sur les versions 64 bits de Windows. Dans .NET, utilisez la valeur par défaut "any CPU" option de compilation pour votre application, je trouve que je suis seulement en mesure d'allouer environ 1,5 GO de mémoire dans le tas (même sur une version 64 bits de Windows de la machine), qui est parce que l'application ne s'exécute en mode 32 bits lorsqu'il est construit en "any CPU" mode. Mais en compilant à l'architecture 64 bits, vous pouvez allouer beaucoup, beaucoup plus de mémoire dans le tas au cours de l'exécution de votre application, et je vais vous expliquer comment créer une version x64 pour votre demande ci-dessous:
De nouveau, à l'aide de la normale (par défaut) "any CPU" option de compilation dans votre .NET de projet, votre demande sera TOUJOURS exécuté en vertu de la mode 32 bits, même sur une version 64 bits de Windows OS. Donc vous ne serez pas en mesure d'allouer plus de 1,5 à 2 GO de RAM de mémoire lors de l'exécution de l'application. Pour exécuter votre .NET application dans le vrai mode 64 bits, vous devrez aller dans la configuration de build manager et créer un type de construction pour l'architecture 64 bits, puis recompiler votre programme pour x64 explicitement aide de ce type de build. La version x64 de l'option de mode peut être créé pour vous .NET solution en utilisant les étapes suivantes:
Aide d'une version 64 bits de votre application sur un Windows 64 bits de l'OS permettra à votre programme d'allouer beaucoup plus de ~2 go de mémoire, sans doute jusqu'à 2^64 adresses des espaces (si vous avez la mémoire vive et d'espace disque disponible, qui sont les véritables facteurs limitants comme du temps de la rédaction de cette réponse).
Si vous êtes TOUJOURS à court de mémoire dans votre application, vous pouvez également augmenter la taille de la mémoire de Windows fichier de la page. Sur Windows, le fichier de page permet au système d'exploitation de maj de la mémoire de la RAM sur le disque, si elle est à court de mémoire RAM espace. Mais il y a un gros coût de temps dans les changements de sections de mémoire RAM et du disque, de sorte qu'il peut être un succès réel sur les performances de votre application. Indépendamment de la performance, par l'augmentation de la taille de la page, vous pouvez (en théorie) de la page fichiers de il y a de l'espace libre disponible sur le disque C: de votre ordinateur windows. Dans ce cas, votre demande serait en mesure d'allouer, par exemple, jusqu'à 4 to de mémoire (ou quelle que soit la quantité de mémoire que votre taille de fichier de page est définie) pendant l'exécution de votre programme. Pour modifier le fichier de page de paramètres pour votre machine Windows, procédez de la manière suivante:
De toute façon, j'espère que cela aide les gens à comprendre pourquoi ils peuvent courir dans cette de 1,5 - 2 GO de mémoire limitation problème dans une .NET application, même lors de l'exécution sur un Windows 64 bits de la machine. Cela peut être un problème très déroutant pour les gens et j'espère que mon explication est logique. N'hésitez pas à me le message avec des questions à propos de cette réponse si nécessaire.
Je pense que le problème ici est que cette application va être l'ajout de 10 MO à chaque boucle la rend, et la boucle est: "while(true)", ce qui signifie qu'il sera l'ajout de ces 10MBs jusqu'à l'application est arrêtée. Donc si c'était à exécuter pour 100 de la boucle, il aurait ajouté près de 1GBs de RAM, et je suis en supposant qu'elle l'aurait fait cela en moins de 30 secondes. Mon point est que vous tentez de 10 méga-octets de mémoire par boucle, dans une interminable boucle
Je suis vraiment désolé si je ne reçois pas votre point, mais:
Avez-vous essayé l'aide de la méthode? Et ce pourrait être une question stupide, mais pourquoi avez-vous créé une boucle sans fin? O si vous essayez le code de supprimer les symboles >.> xD.
Source: http://msdn.microsoft.com/en-us/library/yh598w02(v=vs. 80).aspx