Freigeben über


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
  • 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 diesen OutOfMemoryExceptionauftreten.

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 CodeHeapReserveForJumpStubsnicht, 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 OutOfMemoryExceptionausgelöst hat, ist die einzige empfohlene Möglichkeit zur Wiederherstellung ein Neustart der Anwendung.