96 votes

Pourquoi Large Object Heap et pourquoi nous en soucions-nous?

J'ai lu sur Generations et Large object heap. Mais je n'arrive toujours pas à comprendre quelle est la signification (ou l'avantage) d'avoir un tas d'objets volumineux?

Qu'est-ce qui aurait pu mal se passer (en termes de performances ou de mémoire) si le CLR venait de s'appuyer sur la génération 2 (considérant que le seuil pour Gen0 et Gen1 est petit pour gérer des objets volumineux) pour le stockage d'objets volumineux?

189voto

Hans Passant Points 475940

Une collecte des ordures n'est pas seulement se débarrasser de non référencées objets, elle aussi compacte du segment. C'est un élément très important de l'optimisation. Il n'est pas seulement que l'utilisation de la mémoire plus efficace (pas de trous inutilisés), il rend le cache du PROCESSEUR beaucoup plus efficace. Le cache est vraiment une grosse affaire sur les processeurs modernes, ils sont un simple ordre de grandeur plus rapide que le bus mémoire.

Le compactage est réalisé par un simple copier-octets. Cela, cependant, prend du temps. La plus grande de l'objet, plus il est probable que le coût de la copie qu'elle l'emporte sur la possible de cache du PROCESSEUR de l'utilisation des améliorations.

Ils ont couru un tas de critères de référence pour déterminer le seuil de rentabilité. Et arrivé à 85 000 octets que le point de coupure en cas de copie n'est plus améliore les perf. Avec une exception spéciale pour les tableaux de double, ils sont considérés comme des "gros" quand le tableau a plus de 1000 éléments. C'est une autre optimisation de code 32 bits, le gros tas d'objets allocateur a la propriété particulière qu'il alloue de la mémoire à des adresses qui sont conformes à 8, à la différence de l'ordinaire générationnel allocateur qui n'alloue aligné à 4. Cet alignement est un gros problème pour le double, de la lecture ou de l'écriture d'un mal alignée en double est très cher. Bizarrement les rares Microsoft info ne jamais parler de tableaux de long, pas sûr de ce que ça se fait.

Fwiw, il y a beaucoup de programmeur angoisse sur le tas d'objets volumineux ne pas obtenir compacté. Invariablement, on est déclenchée lorsqu'ils écrivent des programmes qui consomment plus de la moitié de l'ensemble de l'espace d'adressage disponible. Suivi par l'utilisation d'un outil comme un profileur de mémoire, afin de savoir pourquoi le programme bombardé même si il y avait toujours beaucoup de inutilisés de la mémoire virtuelle disponible. Un tel outil montre les trous dans la liturgie des heures, non utilisé des morceaux de mémoire où, auparavant, un objet de grande taille vécu, mais il a obtenu des ordures collectées. Tel est le prix inévitable de la liturgie des heures, le trou ne peut être ré-utilisé par une allocation pour un objet qui est égale ou plus petite en taille. Le vrai problème, c'est en supposant qu'un programme devrait être autorisé à consommer toute la mémoire virtuelle à tout moment.

Un problème qui, autrement, disparaît complètement en exécutant simplement le code sur un système d'exploitation 64 bits. Un processus 64 bits a 8 téra-octets de mémoire virtuelle de l'adresse de l'espace disponible, de 3 ordres de grandeur de plus que d'un processus 32 bits. Vous ne pouvez pas exécuter de trous.

Longue histoire courte, le LOH rend le code de fonctionner plus efficacement. Le coût de l'utilisation de mémoire virtuelle disponible de l'espace d'adresse de moins en moins efficace.


Mise à JOUR, .NET 4.5.1 prend désormais en charge le compactage de la liturgie des heures, GCSettings.LargeObjectHeapCompactionMode de la propriété. Méfiez-vous les conséquences s'il vous plaît.

8voto

oleksii Points 17099

Si la taille de l'objet est supérieure à une valeur épinglée (85 000 octets dans .NET 1), CLR le place ensuite dans le segment Objet de grande taille. Ceci optimise:

  1. Allocation d'objets (les petits objets ne sont pas mélangés avec des gros objets)
  2. Collecte des ordures (LOH collecté uniquement sur la GC complète)
  3. Défragmentation de la mémoire (LOH n'est jamais compacté)

7voto

grapeot Points 841

La différence essentielle des Tas de Petits Objets (SOH) et des Tas d'Objets Volumineux (LOH) est, de mémoire dans SOH obtient compacté lors de la collecte, alors que LOH pas, comme cet article illustre. Le compactage des objets volumineux coûte beaucoup. Similaires avec les exemples de l'article, dire le déplacement d'un octet dans la mémoire a besoin de 2 cycles, puis compactage d'une 8MB objet dans un 2GHz ordinateur a besoin de 8 ms, ce qui est un grand coût. Compte tenu de gros objets (tableaux, dans la plupart des cas) sont très fréquentes dans la pratique, je suppose que c'est la raison pour laquelle Microsoft broches de gros objets dans la mémoire et propose LOH.

BTW, en fonction de ce post, LOH, habituellement, ne génèrent pas de mémoire fragment de problèmes.

2voto

Myles McDonnell Points 3676

Le principe est qu’il est peu probable (et très probablement mal conçu) qu’un processus crée beaucoup d’objets volumineux de courte durée, de sorte que le CLR affecte des objets volumineux à un segment de mémoire distinct sur lequel il exécute GC selon une planification différente de celle du segment de mémoire normal. http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

0voto

Chris Shain Points 33569

Je ne suis pas un expert du CLR, mais j'imagine qu'avoir un tas dédié aux gros objets peut empêcher des balayages de GC inutiles des tas de génération existants. L'affectation d'un objet volumineux nécessite une quantité importante de mémoire libre contiguë . Afin de fournir cela à partir des "trous" dispersés dans les tas de générations, vous aurez besoin de compactions fréquentes (qui ne sont effectuées qu'avec des cycles GC).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X