myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » StackOverflowException bei hoher Zahl an Iterationen
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

StackOverflowException bei hoher Zahl an Iterationen

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Seidenraupe
myCSharp.de-Mitglied

Dabei seit: 05.12.2018
Beiträge: 1
Entwicklungsumgebung: Visual Studio Community 2015


Seidenraupe ist offline

StackOverflowException bei hoher Zahl an Iterationen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich berechne gerade Wahrscheinlichkeiten für ein bestimmtes, komplexes Würfelsystem (Gesellschaftsspiel). Dabei werden vereinfacht gesagt aktuell natürliche Zahlen von 0 bis 99999 rekursiv durchlaufen und auf nicht triviale Weise ausgewertet.

Nach 60830 Zahlenfolgen bekomme ich eine StackOverFlowException.
Es handelt sich jedoch jeweils um unterschiedliche Zahlenfolgen (habe ich im Log nachgeprüft) und daher nicht um eine Endlosschleife. Das Log läuft von 1 1 1 1 1 bis 7 1 9 3 10, dann tritt die Exception auf. Die Exception tritt auch auf, wenn ich das Log ausschalte. Wenn ich nur 10.000 Zahlenfolgen auswerte, funktioniert das Programm einwandfrei. In Zukunft soll das Programm 1.000.000.000 oder mehr Zahlenfolgen auswerten können.

Fehlermeldung:
System.StackOverflowException wurde nicht behandelt.
HResult=-2147023895
Message=Eine Ausnahme vom Typ "System.StackOverflowException" wurde ausgelöst.
InnerException:

Muss ich für ein Programm mit derartig vielen Iterationen etwas besonderes beachten? Kommt der Garbage Collector nicht so schnell hinterher?

Bei der Suche zu dem Problem habe ich nichts passendes gefunden, ich weiß allerdings auch nicht so genau, mit welchen Suchbegriffen ich am ehesten etwas passendes zum Thema finde. Der PC sollte bei so etwas doch nicht überfordert sein? Ich öffne ja keine Ressourcen pro Iteration ohne sie wieder zu schließen.
06.12.2018 23:38 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.353
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wenn du rekursiv arbeitest bedeutet das nur, dass du durch die Menge der rekursiven Methoden Aufrufe eben den Stack zum überlaufen gebracht hat.
Rekursion sollte man nur in geringen Mengen nutzen.

Ich vermute mal, dass dein Code sich auch ohne viel Aufwand auf einen iterativen Ansatz umstellen lässt.
Das dürfte dein Problem auch lösen.

Aber bitte zeig auch mal deinen aktuellen Code der knallt samt den Aufrufen.
Dann kann man dies besser einschätzen!

T-Virus
07.12.2018 08:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.175
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Seidenraupe:
Muss ich für ein Programm mit derartig vielen Iterationen etwas besonderes beachten?

Ja, mit  Stack<> arbeiten; dafür ist es da - denn auch .NET hat ein Stack Limit und wirft danach eine StackOverflowException.
07.12.2018 11:14 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.600
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Seidenraupe,

Zitat:
Muss ich für ein Programm mit derartig vielen Iterationen etwas besonderes beachten?

Iterationen sind eher bei Schleifen angesiedelt, daher Iterationen nicht mit rekursiven Aufrufen verwechseln, denn es sind zwei Paar Schuhe.

Zitat:
Kommt der Garbage Collector nicht so schnell hinterher?

Bei einer StackOverFlowException mischt der Garbage Collector (GC) nicht mit, somit ist es unerheblich wie schnell er ist. Der GC ist für Daten auf dem Heap verantworlich, die von der managed Runtime alloziert werden.

Der Stack ist ein anderer Speicherbereich, bei dem es in der Natur eines Stapelspeichers nur Adress-Inkrementierung / -Dekrementierung gibt und somit kein GC nötig ist.

Für jeden Methodenauruf* werden Daten wie Rücksprungadresse, lokale Variablen, etc. auf den Stack gelegt und bei Rückkehr aus der aufgerufenen Methode wiederhergestellt. Das ist sehr effizient, aber bei vielen Methodenaufrufen, die nicht zurückkehren, kann der erlaubte Stapelspeicherbereich "überlaufen" und das äußert sich eben in einer StackOverFlowException.

* mit ein paar Ausnahmen, wie endrekursive Methodenaufrufe / inlineing außer Acht gelassen

Möglichkeiten zur Behebung / Umgehung sind somit:
  • iteratives Vorgehen verwenden -- wie von T-Virus vorgeschlagen
  • endrekurisves Verhalten (nicht immer leicht)
  • die Stapelspeichergröße erhöhen (ist hier aber eher ein Hack, als eine gute Lösung)
Hallo Abt,

ob Stack<T> passend ist, lässt sich nicht pauschal sagen, da der Algorithmus unbekannt ist.
Z.B. lässt sich

C#-Code:
private static int SumRecursive(int n)
{
    if (n == 1) return 1;

    return n + SumRecursive(n - 1);
}

ohne Stack<T> in eine iterative Variante überführen:

C#-Code:
private static int SumIterative(int n)
{
    int sum = 0;

    for (int i = 1; i <= n; ++i)
        sum += i;

    return sum;
}

mfG Gü
07.12.2018 11:17 Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.175
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Den Übertrag in eine iterative Weise zweifle ich auch nicht an; aber um eine StackOverflow-Exception zu vermeiden hilft im ersten Schritt eigentlich immer Stack<>.
07.12.2018 11:30 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.600
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Abt,

Zitat:
StackOverflow-Exception zu vermeiden hilft

das in meinem Kommentar oben steht ;-)

Der Weg via Stack<t> ist auch nicht immer ganz einfach und da kann der Code gleich richtig geändert werden.

Siehe dazu auch  Forumssuche nach hanoi

mfG Gü
07.12.2018 11:38 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 11 Monate.
Der letzte Beitrag ist älter als 11 Monate.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 17.11.2019 07:00