Kann ein Upgrade von 2 GB auf 4 GB Stack Overflow-Ausnahmen verhindern?

8

Mein PC hat 2 GB RAM-Speicher. Wenn ich ein 3D-Mesh-Objekt mit einem Array von 70.000 Elementen in C # 2008 Express Edition formiere, erhalte ich die Fehlermeldung "Stack Overflow exception handled ...". Wenn ich RAM-Speicher von 2 GB auf 4 GB aufrüste, kann ich diese Fehlermeldung umgehen?

    
Michael Petrotta 02.06.2009, 21:14
quelle

7 Antworten

19

Fast sicher nicht . Ein Stack-Überlauf (und nicht zu wenig Arbeitsspeicher) bedeutet, dass Sie den zugewiesenen Stack Space verbraucht haben - aber der Stack ist (relativ gesehen) klein. Der Heap ist der Ort, an dem alles passiert ...

Optionen:

  • behebe deinen unendlichen Rekursionsfehler ...
  • Verschiebe die Daten in ein Array / eine Liste / einen Heap-basierten Speicher (wo ist es im Moment?)
  • Vermeide tiefe Rekursion
  • Vermeide übergroße Strukturen ... hast du einige große fette Strukturen, die eigentlich Klassen sein sollten? (Strukturen kopieren sich selbst, wenn Sie nur blinzeln)
  • erhöhen Sie den Stack-Bereich wenn Sie sich sicher sind, dass Sie es nur kippen, und es ist keinen großen Refaktor wert (Ich hasse diese Antwort) - um dies zu tun, müssten Sie spawnen Sie Ihren eigenen Thread mit einem größeren Stack
Marc Gravell 02.06.2009 21:17
quelle
11

Nein. Durch Erhöhen des Arbeitsspeichers wird die Stapelgröße nicht erhöht.

Sie schreiben Code, der den Stack-Überlauf verursacht (vielleicht aufgrund von Rekursion), und Sie müssen das beheben.

    
Michael Todd 02.06.2009 21:16
quelle
3

Der physische Speicher beeinflusst nur die Leistung der Programme, die auf der Maschine ausgeführt werden, hat aber nichts mit speicherbedingten Problemen eines Programms zu tun (bei Standard-Betriebssystemen muss das System andere Regeln befolgen).

Erstens, weil ich diesen Fehler sehr oft gesehen habe, sprechen wir über das Speichermodell des Betriebssystems.

Fast jedes Benutzer-Betriebssystem (ich denke hier an Linux, Windows, BSD usw.) verwendet ein virtuelles Speichermodell. Virtuelles Speichermodell bedeutet, dass jedes Programm vollen Zugriff auf einen privaten virtuellen Speicher erhält, dh eine Darstellung von Speicher, die nicht den entsprechenden physischen Speicher haben muss.

Die Größe dieses virtuellen Speichers entspricht dem Bereich, der von einem einzelnen Maschinenregister adressiert werden kann. Auf 32-Bit-Betriebssystemen bedeutet das etwa 4 GB. Jetzt wird Ihr Programm unabhängig davon, wie viel tatsächlicher Speicher Ihr System hat, immer denken, dass er 4 GB hat.

Nun, diese 4 GB werden tatsächlich zwischen Ihrem Programm und dem Speicherplatz aufgeteilt, den das Betriebssystem für den Umgang mit Daten im Kernel-Modus reserviert und die von Ihrem Programm benötigten Strukturen verwaltet. Praktisch können Sie mit etwa 2 oder 3 GB rechnen, abhängig von Ihrer Konfiguration (Ihrer Betriebssystemkonfiguration). All das hat nichts mit der Menge an physischem Speicher zu tun, die Sie haben, Sie können 256 MB RAM haben und Ihr Programm wird immer noch denken, dass ihm 2 GB zur Verfügung stehen.

Wenn Sie Speicher reservieren, liefert das System normalerweise nicht genau die Menge an Speicher, nach der Sie fragen. Stattdessen werden Seiten verwendet, bei denen es sich um Blöcke reservierten Speichers (z. B. 4 KB) handelt, die für Ihren Prozess zugewiesen sind. Wenn Sie das tun, registriert das Betriebssystem, dass "Seite" wie zugewiesen, aber das ist immer noch im virtuellen Speicher. Intern verwaltet das Betriebssystem, welche dieser Seiten auf dem physikalischen Speicher gehalten werden und welche sich im Austausch befinden (auf der Festplatte). Das ist der Grund, dass die Erhöhung Ihres RAM die Leistung erhöht (mehr Seiten können gleichzeitig im Hauptspeicher sein und Sie müssen weniger von der Festplatte lesen), hilft aber nicht mit einem Stapelüberlauf (oder einer Nicht-Speicher-Ausnahme von der Weg).

Und das warum die Erhöhung Ihres RAM wird nicht helfen.

Schließlich, über die Stack Overflow-Ausnahme ... Nun, es ist schwer zu sagen, ohne den tatsächlichen Code zu sehen, einige gute Antworten wurden bereits gegeben.

Meistens kommt der Stapelüberlauf aus einer unendlichen Rekursion, entweder direkt oder indirekt (A - & gt; B - & gt; C - & gt; A), aber in Ihrem konkreten Fall würde ich sagen, dass Sie nur zu viel zuweisen Daten im Stapel.

Sie haben ein Array mit einer Größe von 70000. Ich vermute, dass Array voll von Werttypen ist, die im Stapel zugeordnet sind, die, wenn ich mich richtig erinnere (und bitte nicht das als Tatsache nehmen) 1 MB in .NET ist, was der Grund sein könnte, warum Sie bekommen Ihr Stapelüberlauf.

    
Jorge Córdoba 02.06.2009 21:30
quelle
2

Wahrscheinlich nicht. Sie sollten vergrößern Sie die Stack-Größe , so heißt es in der Fehlermeldung

Bearbeiten: Oder korrigieren Sie die unendliche Rekursion, die Sie wahrscheinlich in Ihrem Code haben.

    
erikkallen 02.06.2009 21:19
quelle
2

Ein Stapelüberlauf kann eine unendliche Rekursion ODER eine sehr tief verschachtelte bedeuten.

Wenn Sie tail-rekursive Methoden haben, wird der x64 JITter sie optimieren und Sie werden überhaupt keine Stack-Überläufe ausführen (und Ihre unendliche Rekursion wird ... unendlich sein).

Sie könnten also auf ein 64-Bit-Betriebssystem aktualisieren oder Ihren Code reparieren, um nicht auf dieses Problem einzugehen (was eher ein Fehler ist als eine zu tief verschachtelte Rekursion ...)

    
Yann Schwartz 02.06.2009 21:28
quelle
1

Eigentlich nein. Aber ich habe einen anderen Grund: Windows XP kann nur bis zu 2 GB verarbeiten, wenn Sie in boot.ini keine bestimmte Bootoption angeben. (Der / 3gb-Parameter.) Im besten Fall gehen Windows XP und Vista bis zu 3 GB RAM, und das ist im Grunde die Grenze für Windows. Weitere Informationen zu diesen Beschränkungen finden Sie unter Dieser Link .

Wenn Sie Ihren RAM-Speicher erhöhen und Ihre Anwendung so reparieren, dass sie die Grenze von 2 GB überschreitet, könnte dies Ihren Stack-Überlauf beheben, da dies die Größe Ihres Stacks erhöhen könnte. Es könnte auch den Moment dieses Stack-Überlaufs verzögern, da sich Ihr Code, wie vorgeschlagen, in einer endlosen rekursiven Schleife befindet und so lange weiterläuft, bis keine Ressourcen mehr verfügbar sind.

Wenn Sie Rekursion verwenden, beachten Sie Folgendes: Alles, was Sie mithilfe der Rekursion tun, kann ohne Rekursion neu geschrieben werden. Es gibt keine Ausnahmen von dieser Regel, obwohl der Code nicht einfacher zu lesen ist.

    
Wim ten Brink 02.06.2009 21:35
quelle
0

Ich weiß nicht für C #, aber in Java bedeutet stackoverflow error, dass Sie eine Instanz einer Klasse in der Klasse erstellen, die bereits in der Klasse instanziiert wurde, die Sie instanziieren möchten

    
Filip Stojkovic 21.01.2013 23:56
quelle

Tags und Links