Question

Je me demande pourquoi je ne suis pas en mesure d'allouer plus de 1000 Mo de mémoire dans mon processus .NET 32 bits. La mini-application suivante lance un OutOfMemoryException après avoir alloué 1000 MB. Pourquoi 1000 Mo, et ne pas dire 1,8 Go? Y at-il un cadre de processus à l'échelle que je pourrais 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 ne permet pas

.

Modifier, 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 à la base de données / disque. Au lieu de créer des fichiers temporaires pour tout, j'ai écrit un cache en mémoire, ce qui rend super rapide toute la chose. Mais la mémoire est limitée, et donc j'ai essayé de savoir quelles sont les limites. Et se demande pourquoi mon petit programme de test a jeté le OutOfMemoryException après exactement 1 000 Mo.

Était-ce utile?

La solution

La limite d'espace d'adressage virtuel d'un processus Win32 est de 1,5 Go (pas tout à fait vrai). De plus, dans le cadre .NET il y a un limiteur pour le% de la mémoire d'un processus de .NET peut consommer. Le machine.config comporte un élément processModel avec un attribut memoryLimit qui est le% de mémoire disponible d'un processus peut consommer. La valeur par défaut est de 60%.

Si la machine que vous utilisez sur a 2 Go de mémoire ou si vous avez pas activé le commutateur / 3GB dans votre boot.ini alors vous allez obtenir ~ 1,3 Go de mémoire par processus.

Je ne peux pas trouver l'article KB mais si je me souviens bien 1.x .NET ne peut pas traiter au-delà du 1.5Go (1.8GB?) 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 / fil / c50ea343-B41B-467d-a457-c5a735e4dfff http://www.guidanceshare.com/wiki/ASP.NET_1.1_Performance_Guidelines_ -_Caching # Configure_the_Memory_Limit

Autres conseils

Avoir d'énormes blocs de mémoire est jamais une bonne idée, même en 64bit. Vous obtenez de gros problèmes de mémoire contigus et la fragmentation.

Le problème est de trouver un bloc contigu ici. Vous pouvez essayer d'activer le mode 3GB (qui pourrait l'aider à trouver un peu plus octets) mais je vraiment déconseiller. Les réponses sont ici:

  • utiliser moins de mémoire
  • utilisez un système base de données / fichier
  • utilisation x64

Vous pouvez également lire blog Eric Lippert (il semble avoir une entrée de blog pour chaque question .NET commune ...)

Je l'ai fait récemment le profilage étendu autour des limites de mémoire dans .NET sur un processus 32 bits. Nous sommes tous bombardés par l'idée que nous pouvons allouer jusqu'à 2.4GB (2 ^ 31) dans une application .NET, mais malheureusement, ce n'est pas vrai :(. Le processus de demande a beaucoup d'espace à utiliser et le système d'exploitation fait un grand travail sa gestion, elle-même .NET semble cependant avoir ses propres frais généraux qui représente pour nous, environ 600-800MB pour des applications réelles typiques qui poussent la limite de mémoire. Cela signifie que dès que vous allouez un tableau d'entiers qui prend environ 1.4GB, vous devriez vous attendre à voir un OutOfMemoryException ().

Il est évident que dans 64bit, cette limite se voie plus tard (causons en 5 ans :)), mais la taille générale de tout dans la mémoire Croît aussi (je trouve qu'il est ~ 1,7 ~ 2 fois) en raison de la taille de mot augmenté .

Ce que je sais pour sûr est que l'idée de la mémoire virtuelle du système d'exploitation ne vous donne pas vraiment l'espace d'allocation pratiquement sans fin au sein d'un processus. Il est seulement là pour que la pleine 2.4GB est adressable à toutes les applications en cours d'exécution (beaucoup) à un moment donné.

J'espère que cette idée aide un peu.

Je lui ai répondu d'abord quelque chose lié ici (je suis encore un Newby alors je ne suis pas sûr que je suis censé faire ces liens):

Est il une limite de mémoire pour un seul processus de .NET

Vous pouvez allouer beaucoup plus de mémoire ~ 2 Go en construisant votre application à une architecture 64 bits, ce qui suppose que vous créez une nouvelle configuration de construction dans Visual Studio, et que la construction de l'application ne fonctionnera que sur 64 bits les versions de Windows. Dans .NET, en utilisant la valeur par défaut « Any CPU » option de compilation pour votre application, je trouve que je ne suis en mesure d'allouer environ 1,5 Go de mémoire du tas (même sur la machine Windows 64 bits), ce qui est parce que l'application fait ne fonctionne en mode 32 bits lorsqu'il est construit en mode « Tout CPU ». Mais en compilant à l'architecture x64, vous pouvez allouer beaucoup, beaucoup plus de mémoire dans le tas lors de l'exécution de votre application, et je vais vous expliquer comment créer un x64 construire pour votre application ci-dessous:

Encore une fois, en utilisant la normale (par défaut) option « Tout CPU » construire dans votre projet .NET, votre application fonctionnera toujours en mode 32 bits, même sur un système d'exploitation Windows 64 bits. Par conséquent, vous ne serez pas en mesure d'allouer plus d'environ 1,5 à 2 Go de mémoire RAM lors de l'exécution de l'application. Pour exécuter votre application .NET en vrai mode 64 bits, vous devrez aller dans le gestionnaire de configuration de construction et de créer un type de construction pour l'architecture x64, puis recompiler votre programme pour x64 en utilisant explicitement ce type de construction. L'option de mode de construction x64 peut être créé pour votre solution .NET en procédant comme suit:

  1. Dans le volet Visual Studio « Solution Explorer », faites un clic droit sur l'icône de la solution et choisissez l'option « Configuration Manager » dans le menu contextuel. Cela ouvrira la construction « Configuration Manager » fenêtre de dialogue pour le fichier de solution .NET.
  2. A droite, côté haut de la construction de dialogue « Configuration Manager », cliquez sur la flèche vers le bas et sélectionnez l'option « ». Cela ouvrira la boîte de dialogue « une nouvelle solution plate-forme ».
  3. Dans la boîte de dialogue « une nouvelle solution plate-forme » pour l'option « plate-forme », choisissez « x64 » dans le menu déroulant. Cliquez ensuite sur le bouton « OK » et la nouvelle option de construction x64 sera désormais disponible dans la boîte de dialogue Configuration Manager.
  4. Ensuite, la boîte de dialogue « Configuration Manager », sélectionnez « x64 » dans le menu déroulant « Plate-forme de la solution active ». Le cliquez sur le bouton « Fermer ».
  5. Dans le volet Visual Studio « Solution Explorer », faites un clic droit sur l'icône du projet CS et choisissez l'option « Propriétés » dans le menu contextuel (la dernière option en bas de ce menu). Cela ouvrira la fenêtre des propriétés du projet CS.
  6. Sur le côté gauche de la fenêtre Propriétés du projet CS, cliquez sur l'onglet « Build » pour afficher les propriétés de construction pour votre projet de code. En haut de cette fenêtre, notez que la « plate-forme » devrait maintenant dire « x64 » (en option, par opposition à la valeur par défaut « Tout CPU »). Si la « plate-forme » déroulante ne montre pas « x64 », vous devez sélectionner maintenant.
  7. Ensuite, il suffit de construire votre code et dans le dossier « bin », vous devriez maintenant avoir un dossier x64 avec la nouvelle version 64 bits de votre application à l'intérieur.

En utilisant une version 64 bits de votre application sur un Windows 64 bits OS permettra à votre programme d'allouer beaucoup plus que ~ 2 Go de mémoire, probablement jusqu'à 2 ^ 64 espaces d'adressage (si vous avez la RAM et l'espace disque disponibles, qui sont les véritables facteurs limitants du moment de la rédaction de cette réponse).

Si vous utilisez encore hors de la mémoire dans votre application, vous pouvez également augmenter la taille du fichier de page de mémoire de Windows. Sous Windows, le fichier de page permet au système d'exploitation pour déplacer la mémoire de la RAM sur le disque, si elle manque d'espace mémoire RAM. Mais il y a un coût énorme de temps en déplacement sections de mémoire RAM et à partir du disque, il peut donc être un véritable succès sur les performances de votre application. Quelle que soit la performance, en augmentant la taille de la page, vous pouvez (en théorie) rendre le fichier page aussi grand que l'espace libre disponible sur le lecteur C: de votre machine Windows. Dans ce cas, votre demande serait en mesure d'allouer, par exemple, jusqu'à 4 Tode la mémoire (ou quel que soit la quantité de mémoire que la taille de votre fichier de page est réglé sur) lors de l'exécution de votre programme. Pour modifier les paramètres du fichier de page pour votre machine Windows, procédez comme suit:

  1. Ouvrez l'option « Propriétés système » dialogue par un clic droit sur « Ce PC » et choisir « Propriétés » dans le menu contextuel. Cela peut aussi se faire dans les versions ultérieures de Windows (Windows 10, Windows 2012 Server, etc ...) en allant dans « Démarrer »> « Panneau de configuration »> « Système et sécurité »> « Système ».
  2. Sur le côté gauche de la boîte de dialogue « Système », cliquez sur l'option « Advanced System Properties ». Cela montrera l'onglet « Avancé » de l'héritage « Propriétés système » dialogue pour Windows.
  3. Dans l'onglet « Avancé » de la boîte de dialogue « Propriétés système », cliquez sur le bouton « Paramètres » dans la boîte « Performance ». Cela ouvrira la boîte de dialogue « Options de performances ».
  4. Sur la boîte de dialogue « Options de performances », cliquez sur l'onglet « Avancé » pour voir le réglage actuel de la taille du fichier de page de mémoire de Windows.
  5. Pour augmenter la taille du fichier de page, cliquez sur le bouton « Modifier » et la boîte de dialogue « Mémoire virtuelle » sera ouvert.
  6. Sur la boîte de dialogue « Mémoire virtuelle », sélectionnez « C: » lecteur, puis sous « Taille personnalisée », définissez les tailles « initiales » et « Maximum ». Vous pouvez utiliser toute taille jusqu'à la quantité maximale d'espace libre sur le disque C:, mais ce changement réserve que l'espace pour le fichier de page sur le disque dur.
  7. Puis cliquez sur « Ok » sur toutes les boîtes de dialogue pour valider les nouveaux paramètres. Ensuite, redémarrez votre ordinateur pour que tous les changements ont été correctement remplis et que les nouveaux paramètres du fichier de page sont en fonctionnement.

Quoi qu'il en soit, j'espère que cela aide les gens à comprendre pourquoi ils peuvent courir dans ce 1,5 à 2 Go question de la prescription de la mémoire dans une application .NET, même lors de l'exécution sur une machine Windows 64 bits. Cela peut être un problème très déroutant pour les gens et j'espère que mon explication est logique. S'il vous plaît ne hésitez pas à me message avec des questions sur cette réponse si nécessaire.

Je pense que le problème est que cette application ajoutera 10MB avec chaque boucle, il fait, et la boucle est: « while (true) » ce qui signifie qu'il l'ajout de ces 10Mbs jusqu'à ce que l'application est arrêtée. Donc, si elle devait courir pour 100 boucle, il aurait ajouté près de 1GBs à la RAM, et je suppose qu'il aurait fait cela en moins de 30 secondes. Mon point est que vous essayez de 10 méga-octets de mémoire par de la boucle, dans une boucle sans fin

Je suis vraiment désolé si je ne pas votre point, mais:

static void Main(string[] 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 en utilisant? 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 / fr-fr / bibliothèque / yh598w02 (v = vs.80) .aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top