Eine Ausnahme vom Typ "Nicht genügend Arbeitsspeicher" in einer verwalteten Anwendung, die auf der 64-Bit-.NET Framework
Dieser Artikel hilft Ihnen, die Ausnahme von "Nicht genügend 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
Symptome
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 vom Typ "Nicht genügend Arbeitsspeicher" 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 vom Typ "Nicht genügend Arbeitsspeicher" wird von der CLR weitergegeben, wenn das Code-Manager-Subsystem keinen Speicher innerhalb eines bestimmten Adressraumbereichs für Sprungstubbs zuordnen kann. (Diese Sprung-Stubs entsprechen der Methode, die zwischen Dynamic-Link-Bibliotheken (DLLs) aufruft, die sich mindestens 2 GB im Adressraum befinden.) Innerhalb eines Radius von 2 GB der aufrufenden Methode muss Speicherplatz vorhanden sein, um den Jump-Stub für einen 64-Bit-Methodenaufruf zu speichern. Es gibt keine sichere Möglichkeit für eine Anwendung, nach diesem spezifischen Fehler wiederherzustellen. Der Status der Anwendung, nachdem dieser Fehler aufgetreten ist, ist also unbekannt und sollte als beschädigt betrachtet werden. Die einzige Möglichkeit zur Wiederherstellung 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 ihrer Anwendungskonfigurationsdatei den folgenden Abschnitt hinzufügen:
<configuration> <runtime> <NGenReserveForJumpStubs value="5" /> </runtime> </configuration>
Hinweis
NGenReserveForJumpStubs
bewirkt, dass die CLR einen Prozentsatz des Adressraums für Sprungstubs in der Nähe jedes geladenen NGen-Images reserviert. Es wird empfohlen, einen Wert von 5 oder höher zu verwenden, wenn sie diesenOutOfMemoryException
auftreten.
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 Aufrufer und Aufgerufener weiter als 2 GB (im Adressraum) voneinander entfernt sein. Da er den Adressbereich eines signierten 32-Bit-Offsets überschreitet, erstellt .NET innerhalb von 2 GB des Aufrufers einen Jump-Stub. Dieser Jump-Stub 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 vorab zusätzlichen Adressraum, aber der Punkt, an dem diese Reservierung vorgenommen wird, unterscheidet sich zwischen den beiden.
NGenReserveForJumpStubs
ist ein Prozentsatz der größe des virtuellen NGen-Images (percentReserveForJumpStubs).Ein typischer Jump-Stub ist 12 Byte. Weitere Informationen finden Sie unter JUMP_ALLOCATE_SIZE.
Der Speicher wird in der Nähe der Adresse zugeordnet und reserviert, an der das NGen-Image geladen wurde (der genaue Algorithmus ist EEJitManager::EnsureJumpStubReserve. Der Arbeitsspeicher wird committet, wenn ein Jump-Stub zugewiesen werden muss und kein anderer geeigneter Adressraum verfügbar ist.
Die zuvor erwähnte Entschärfung ändert den Inhalt von NGen-Images nicht. Die NGen-Images haben den gleichen Datenträgerbedarf mit und ohne Risikominderung.
Es gibt derzeit keine gute Möglichkeit, zu erkennen, wann sich die Anwendung dem Grenzwert nähert. Sie können überwachen, ob der reservierte
OutOfMemoryException
Speicherplatz ausreicht.Sie erhalten möglicherweise auch dann,
OutOfMemoryException
wenn viel nicht verwendeter Arbeitsspeicher vorhanden ist, da dieser spezifische Fehler mit der Verfügbarkeit von Arbeitsspeicher innerhalb eines Adressbereichsradius von 2 GB des Aufrufers zusammenhängt.Ändern Sie den Standardwert von
CodeHeapReserveForJumpStubs
nicht, da er möglicherweise nicht mit dem oben beschriebenen Problem zusammenhängt. Wir haben keinen Fall gesehen, in dem die tatsächliche Anwendung diese Einstellung als Problemumgehung anpassen müsste.Das Festlegen
NGenReserveForJumpStubs
eines höheren Werts kann zu einer verringerten Leistung und dem Risiko führen, dass andere subtile Probleme offenlegen.
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 seltenes Problem, das nur große Workloads betrifft, die ein bestimmtes Ausführungsmuster aufweisen. Bei mehr als 99 Prozent aller Workloads tritt dieses Problem jemals auf.
- Nachdem die Anwendung eine
OutOfMemoryException
ausgelöst hat, ist die einzige empfohlene Möglichkeit zur Wiederherstellung ein Neustart der Anwendung.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für