Eine Garbage Collection entfernt nicht nur nicht referenzierte Objekte, sondern komprimiert auch den Heap. Das ist eine sehr wichtige Optimierung. Dies macht nicht nur die Speichernutzung effizienter (keine nicht verwendeten Lücken), sondern auch den CPU-Cache wesentlich effizienter. Der Cache ist bei modernen Prozessoren eine große Sache, sie sind eine einfache Größenordnung schneller als der Speicherbus.
Die Komprimierung erfolgt einfach durch Kopieren von Bytes. Das braucht jedoch Zeit. Je größer das Objekt ist, desto wahrscheinlicher überwiegen die Kosten für das Kopieren die möglichen Verbesserungen der CPU-Cache-Nutzung.
Deshalb haben sie eine Reihe von Benchmarks durchgeführt, um den Break-Even-Punkt zu bestimmen. Und kam zu 85.000 Bytes als Grenzwert, an dem das Kopieren die Leistung nicht mehr verbessert. Mit einer besonderen Ausnahme für Double-Arrays gelten sie als "groß", wenn das Array mehr als 1000 Elemente enthält. Dies ist eine weitere Optimierung für 32-Bit-Code. Der Heap-Allokator für große Objekte verfügt über die spezielle Eigenschaft, dass er Speicher an Adressen zuweist, die auf 8 ausgerichtet sind, im Gegensatz zum regulären Generations-Allokator, der nur auf 4 ausgerichtet ist. Diese Ausrichtung ist eine große Sache für das Doppelte Das Lesen oder Schreiben eines falsch ausgerichteten Doppels ist sehr teuer. Seltsamerweise erwähnen die spärlichen Microsoft-Informationen niemals lange Arrays, nicht sicher, was damit los ist.
Fwiw, es gibt viele Programmiererangst darüber, dass der große Objekthaufen nicht komprimiert wird. Dies wird immer dann ausgelöst, wenn Programme geschrieben werden, die mehr als die Hälfte des gesamten verfügbaren Adressraums belegen. Verwenden Sie anschließend ein Tool wie einen Speicherprofiler, um herauszufinden, warum das Programm bombardiert wurde, obwohl noch viel nicht verwendeter virtueller Speicher verfügbar war. Ein solches Werkzeug zeigt die Löcher im LOH, unbenutzte Speicherblöcke, in denen zuvor ein großes Objekt lebte, aber Müll gesammelt wurde. Dies ist der unvermeidliche Preis des LOH. Das Loch kann nur durch eine Zuordnung für ein Objekt mit gleicher oder kleinerer Größe wiederverwendet werden. Das eigentliche Problem besteht darin, dass ein Programm jederzeit den gesamten virtuellen Speicher belegen darf .
Ein Problem, das ansonsten vollständig verschwindet, wenn nur der Code auf einem 64-Bit-Betriebssystem ausgeführt wird. Bei einem 64-Bit-Prozess stehen 8 Terabyte Adressraum für den virtuellen Speicher zur Verfügung, 3 Größenordnungen mehr als bei einem 32-Bit-Prozess. Ihnen können einfach keine Löcher ausgehen.
Kurz gesagt, das LOH macht den Code effizienter. Auf Kosten der Nutzung des verfügbaren virtuellen Speicheradressraums weniger effizient.
UPDATE, .NET 4.5.1 unterstützt jetzt das Komprimieren der Eigenschaft LOH, GCSettings.LargeObjectHeapCompactionMode . Beachten Sie bitte die Konsequenzen.