Un garbage collection ne se débarrasse pas seulement des objets non référencés, il compacte également le tas. C'est une optimisation très importante. Cela ne rend pas seulement l'utilisation de la mémoire plus efficace (pas de trous inutilisés), cela rend le cache du processeur beaucoup plus efficace. Le cache est un très gros problème sur les processeurs modernes, ils sont d'un ordre de grandeur facile plus rapides que le bus mémoire.
Le compactage se fait simplement en copiant des octets. Cela prend cependant du temps. Plus l'objet est grand, plus il est probable que le coût de sa copie l'emporte sur les améliorations possibles de l'utilisation du cache du processeur.
Ils ont donc exécuté une série de points de repère pour déterminer le seuil de rentabilité. Et arrivé à 85 000 octets comme point de coupure où la copie n'améliore plus les performances. Avec une exception spéciale pour les tableaux de double, ils sont considérés comme «grands» lorsque le tableau contient plus de 1000 éléments. C'est une autre optimisation pour le code 32 bits, l'allocateur de tas d'objets volumineux a la propriété spéciale d'allouer de la mémoire à des adresses alignées sur 8, contrairement à l'allocateur générationnel régulier qui alloue uniquement aligné sur 4. Cet alignement est un gros problème pour le double , lire ou écrire un double mal aligné coûte très cher. Curieusement, les informations Microsoft clairsemées ne mentionnent jamais de tableaux de longue durée, je ne sais pas ce qui se passe avec cela.
Fwiw, il y a beaucoup d'angoisse du programmeur à propos du gros tas d'objets qui ne soit pas compacté. Cela se déclenche invariablement lorsqu'ils écrivent des programmes qui consomment plus de la moitié de tout l'espace d'adressage disponible. Suivi en utilisant un outil comme un profileur de mémoire pour découvrir pourquoi le programme a bombardé même s'il y avait encore beaucoup de mémoire virtuelle inutilisée disponible. Un tel outil montre les trous dans la LOH, des blocs de mémoire inutilisés où auparavant un gros objet vivait mais était récupéré. Tel est le prix inévitable du LOH, le trou ne peut être réutilisé que par une allocation pour un objet de taille égale ou inférieure. Le vrai problème est de supposer 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éraoctets d'espace d'adressage de mémoire virtuelle disponibles, 3 ordres de grandeur de plus qu'un processus 32 bits. Vous ne pouvez tout simplement pas manquer de trous.
Pour faire court, la LOH rend le code plus efficace. Au détriment de l'utilisation de l'espace d'adressage de la mémoire virtuelle disponible moins efficace.
UPDATE, .NET 4.5.1 prend désormais en charge le compactage de la propriété LOH, GCSettings.LargeObjectHeapCompactionMode . Méfiez-vous des conséquences s'il vous plaît.