Eine Out-of-Memory-Ausnahme in einer verwalteten Anwendung, die im 64-Bit-.NET Framework ausgeführt wird
Dieser Artikel hilft Ihnen, die Ausnahme außerhalb des Arbeitsspeichers zu beheben, wenn Sie über eine verwaltete Anwendung verfügen, die auf die 64-Bit-Version von Microsoft .NET Framework 4.6.1 ausgerichtet ist.
Originalproduktversion: .NET Framework 4.6.1
Ursprüngliche KB-Nummer: 3152158
Problembeschreibung
Sie verfügen über eine verwaltete Anwendung, die auf die 64-Bit-Version von .NET Framework 4.6.1 ausgerichtet ist. Diese Anwendung löst eine Out-of-Memory-Ausnahme aus der Common Language Runtime (CLR) mit der folgenden spezifischen Meldung aus:
OutOfMemoryException: "Unzureichender Arbeitsspeicher innerhalb des angegebenen Adressraumbereichs, um die Ausführung des Programms fortzusetzen."
Ursache
Diese Out-of-Memory-Ausnahme wird von der CLR weitergegeben, wenn das Code-Manager-Subsystem Speicher innerhalb eines bestimmten Adressraumbereichs für Sprung-Stubs nicht zuordnen kann. (Diese Sprung-Stubs entsprechen der Methode, die unter DlLs (Dynamic Link Libraries) aufruft, die sich 2 GB oder mehr im Adressbereich befinden.) Es muss Platz innerhalb eines 2-GB-Radius der aufrufenden Methode vorhanden sein, um den Sprungstub für einen 64-Bit-Methodenaufruf zu speichern. Es gibt keine sichere Möglichkeit für eine Anwendung, aus diesem spezifischen Fehler wiederherzustellen. Der Zustand der Anwendung, nachdem er diesen Fehler erfüllt hat, ist unbekannt und sollte als beschädigt betrachtet werden. Die einzige Möglichkeit zum Wiederherstellen besteht darin, die Anwendung neu zu starten.
Problemumgehung
Verwenden Sie eine der folgenden Einstellungsmethoden, um dieses Problem zu umgehen:
Implementieren Sie eine computerweite Einstellung, indem Sie den folgenden Registrierungsschlüssel hinzufügen:
- Ort:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
- Type: DWORD
- Name: NGenReserveForjumpStubs
- Wert: 00000005
- Ort:
Implementieren Sie eine Einstellung auf Anwendungsebene, indem Sie der Anwendungskonfigurationsdatei den folgenden Abschnitt hinzufügen:
<configuration> <runtime> <NGenReserveForJumpStubs value="5" /> </runtime> </configuration>
Notiz
NGenReserveForJumpStubs
bewirkt, dass die CLR einen Prozentsatz des Adressraums für Sprung-Stubs in der Nähe jedes geladenen NGen-Bilds reserviert. Es wird empfohlen, einen Wert von 5 oder höher zu verwenden, wenn dies auftrittOutOfMemoryException
.
Informationen für Entwickler
Aus Leistungsgründen codiert .NET Framework Methodenaufrufe als relative 32-Bit-Sprünge. Auf einem 64-Bit-System können Anrufer und Angerufene weiter als 2 GB (im Adressraum) voneinander entfernt sein. Da er den Adressbereich eines signierten 32-Bit-Offsets überschreitet, erstellt .NET einen Sprung-Stub innerhalb von 2 GB des Aufrufers. Dieser Sprungstub kann dann den langen Sprung zu einer beliebigen Stelle im 64-Bit-Adressraum machen.
Die JIT- und NGen-Entschärfungen funktionieren etwas anders. Beide reservieren vorn zusätzlichen Adressraum, aber der Punkt, an dem diese Reservierung erfolgt, unterscheidet sich zwischen den beiden.
NGenReserveForJumpStubs
ist ein Prozentsatz der virtuellen NGen-Bildgröße (percentReserveForJumpStubs).Ein typischer Sprungstub beträgt 12 Byte. Weitere Informationen finden Sie unter JUMP_ALLOCATE_SIZE.
Der Speicher wird zugewiesen und in der Nähe der Adresse reserviert, an der das NGen-Bild geladen wurde (der genaue Algorithmus ist EEJitManager::EnsureJumpStubReserve. Der Speicher wird zugesichert, wenn ein Sprungstub zugewiesen werden muss, und wenn kein anderer geeigneter Adressraum verfügbar ist.
Die oben erwähnte Entschärfung ändert den Inhalt von NGen-Bildern nicht. Die NGen-Images weisen denselben Datenträgerbedarf sowohl mit als auch ohne Entschärfung auf.
Es gibt derzeit keine gute Möglichkeit, zu erkennen, wann die Anwendung sich dem Grenzwert nähert. Sie können überwachen
OutOfMemoryException
, ob der reservierte Speicherplatz ausreicht.Möglicherweise erhalten Sie auch dann,
OutOfMemoryException
wenn viel nicht verwendeter Arbeitsspeicher vorhanden ist, da dieser spezifische Fehler mit der Verfügbarkeit des Speichers innerhalb eines 2-GB-Adressbereichsradius des Anrufers zusammenhängt.Ändern Sie nicht den Standardwert von
CodeHeapReserveForJumpStubs
, da er möglicherweise nicht mit dem oben beschriebenen Problem verknüpft ist. Wir haben keinen Fall gesehen, in dem die tatsächliche Anwendung diese Einstellung als Problemumgehung anpassen müsste.Die Einstellung
NGenReserveForJumpStubs
auf einen höheren Wert kann zu einer verringerten Leistung und zum Risiko führen, dass andere subtile Probleme auftreten.
Informationen für IT-Benutzer
- Dieses Problem kann auch in anderen Versionen von .NET Framework auftreten. Die Problemumgehung gilt derzeit jedoch nur für .NET Framework 4.6.1.
- Es ist ein seltenes Problem, das nur große Workloads betrifft, die ein bestimmtes Ausführungsmuster aufweisen. Bei mehr als 99 Prozent aller Workloads wird dieses Problem nie auftreten.
- Nachdem die Anwendung einen
OutOfMemoryException
Fehler ausgelöst hat, empfiehlt es sich, die Anwendung neu zu starten.