Eine Ausnahme aufgrund von nicht genügend Arbeitsspeicher in einer verwalteten Anwendung, die auf dem 64-Bit-.NET Framework
Dieser Artikel hilft Ihnen, die Ausnahme zu wenig Arbeitsspeicher 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.
Ursprüngliche Produktversion: .NET Framework 4.6.1
Ursprüngliche KB-Nummer: 3152158
Problembeschreibung
Sie verfügen über eine verwaltete Anwendung, die auf die 64-Bit-.NET Framework 4.6.1 ausgerichtet ist. Diese Anwendung löst eine Ausnahme außerhalb des Arbeitsspeichers aus der Common Language Runtime (CLR) mit der folgenden spezifischen Meldung aus:
OutOfMemoryException: "Nicht genügend Arbeitsspeicher innerhalb des angegebenen Adressraumbereichs, um die Ausführung des Programms fortzusetzen."
Ursache
Diese Ausnahme außerhalb des Arbeitsspeichers wird vom CLR weitergegeben, wenn das Code-Manager-Subsystem keinen Speicher innerhalb eines bestimmten Adressraumbereichs für Sprungstubs zuordnen kann. (Diese Sprung-Stubs entsprechen der Methode, die Aufrufe zwischen Dynamic Link Libraries (DLLs) aufruft, die sich 2 GB oder mehr im Adressraum befinden.) Es muss speicherplatz innerhalb eines Radius von 2 GB 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, nach diesem spezifischen Fehler wiederherzustellen. Daher ist der Status der Anwendung, nachdem sie diesen Fehler erfüllt hat, 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:
- Lage:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework - Typ: DWORD
- Name: NGenReserveForjumpStubs
- Wert: 00000005
- Lage:
Implementieren Sie eine Einstellung auf Anwendungsebene, indem Sie der Anwendungskonfigurationsdatei den folgenden Abschnitt hinzufügen:
<configuration> <runtime> <NGenReserveForJumpStubs value="5" /> </runtime> </configuration>Hinweis
NGenReserveForJumpStubsbewirkt, dass die CLR einen Prozentsatz des Adressraums für Sprungstubs in der Nähe jedes geladenen NGen-Bilds reserviert. Es wird empfohlen, dass Sie den Wert 5 oder höher verwenden, wenn Sie diesOutOfMemoryExceptionerfahren.
Informationen für Entwickler
Die .NET Framework codiert Methodenaufrufe aus Leistungsgründen als relative 32-Bit-Sprünge. Auf einem 64-Bit-System können Sich Anrufer und Angerufener weiter als 2 GB (im Adressraum) unterscheiden. Da der Adressbereich eines signierten 32-Bit-Offsets überschritten wird, erstellt .NET einen Sprungstub innerhalb von 2 GB des Aufrufers. Dieser Sprungstub kann dann den langen Sprung zu einer beliebigen Stelle im 64-Bit-Adressraum ausführen.
Die JIT- und NGen-Gegenmaßnahmen funktionieren etwas anders. Beide reservieren im Vorfeld zusätzlichen Adressraum, aber der Punkt, an dem diese Reservierung vorgenommen wird, unterscheidet sich zwischen den beiden.
NGenReserveForJumpStubsist ein Prozentsatz der virtuellen NGen-Bildgröße (percentReserveForJumpStubs).Ein typischer Sprungstub ist 12 Bytes. Weitere Informationen finden Sie unter JUMP_ALLOCATE_SIZE.
Der Speicher wird in der Nähe der Adresse reserviert, an der das NGen-Bild geladen wurde (der genaue Algorithmus ist EEJitManager::EnsureJumpStubReserve. Für den Speicher wird ein Commit ausgeführt, wenn ein Sprungstub zugeordnet werden muss und kein anderer geeigneter Adressraum verfügbar ist.
Die oben genannte Gegenmaßnahme ändert den Inhalt von NGen-Images nicht. Die NGen-Images weisen den gleichen Datenträgerbedarf sowohl mit als auch ohne Gegenmaßnahmen auf.
Es gibt derzeit keine gute Möglichkeit, zu erkennen, wann die Anwendung dem Grenzwert nähert. Sie können
OutOfMemoryExceptionüberwachen, ob der reservierte Speicherplatz ausreicht.Möglicherweise erhalten Sie dies
OutOfMemoryExceptionauch dann, wenn viel nicht genutzter Speicher vorhanden ist, da dieser spezifische Fehler mit der Verfügbarkeit von Arbeitsspeicher innerhalb eines Adressbereichs von 2 GB im Radius des Aufrufers zusammenhängt.Ändern Sie nicht den Standardwert von
CodeHeapReserveForJumpStubs, da er möglicherweise nicht mit dem oben beschriebenen Problem zusammenhängt. Wir haben keinen Fall gesehen, in dem die eigentliche Anwendung diese Einstellung als Problemumgehung anpassen müsste.Das Festlegen
NGenReserveForJumpStubseines höheren Werts kann zu einer verringerten Leistung und dem Risiko führen, dass andere geringfügige Probleme auftreten.
Informationen für IT-Benutzer
- Dieses Problem kann auch in anderen Versionen des .NET Framework auftreten. Die Problemumgehung gilt derzeit jedoch nur für die .NET Framework 4.6.1.
- Es ist ein selten auftretendes Problem, das nur große Workloads betrifft, die ein bestimmtes Ausführungsmuster aufweisen. Dieses Problem tritt bei mehr als 99 Prozent aller Workloads auf.
- Nachdem die Anwendung eine ausgelöst
OutOfMemoryExceptionhat, ist die einzige empfohlene Methode zum Wiederherstellen, die Anwendung neu zu starten.