Stack leeren?

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von BiedermannS.

    Stack leeren?

    Guten Morgen,

    mein Programm (thermodynamische Berechnungen mit vielen iterativen Schleifen zur Optimumsfindung) ist mittlerweile weit gediehen und funktioniert soweit einwandfrei. Allerdings nur, solange die zu betrachtenden Fälle in ihrer Anzahl überschaubar sind. Andernfalls erhalte ich an komplett unterschiedlichen Stellen im Code eine Stack overflox Ecxection. Unendliche Schleifen kann ich ausschließen, so dass ich davon ausgehe, dass der Stack durch mehrhundertmaliges Aufrufen diverser Prozeduren voll ist. Die Frage die sich mir (Informatik-Laie) nun stellt ist, wie leere, bzw. erweitere den Stack/die Auslagerungsdatei ( ?( ) oder was auch immer für die exception verantwortlich ist?

    Da es sich hierbei um Terrain handelt, von dem ich (auch nach Suche im www) absolut keine Ahnung habe, wäre ich für Lösungshinweuse sehr dankbar.
    Merci schonmal :)
    Hi
    verwende statt rekursiven Aufrufen einfach Schleifen. Bei einem Aufruf werden Werte für Instanz, Parameter, Rücksprungadresse, etc. auf dem Stapel abgelegt. Wenn der Stapel also nicht abgebaut wird, füllt er sich stetig. Bei einer Schleife würde das dann eben durch die Jumps verhindert.

    Gruß
    ~blaze~
    Der Heap ist der Speicher, wo die Objekte abgelegt werden. Dieser wird vom GC verwaltet.
    Der Stack ist ein sog. Stapelspeicher und enthält lokale Variablen und Rücksprungadressen. StackOverflow tritt meistens bei zu vielen Rekursionsaufrufen auf, da irgendwann kein Platz mehr für die Rücksprungadressen ist.
    Danke schonmal für die Antworten. Exzessives Suchen führte mich zu folgendem Ansatz:
    Link

    Da mein Programm zwingend einen bestimmten rekursiven mathematischen Algorithmus (welcher immer terminiert) abbilden muss, kommt nur eine Erweiterung des Stack infrage. Die in dem Link dargestellte Vorgehensweise sieht verlockend simpel aus, allerdings finde ich das entsprechende properties-menü nicht ?( . Auch ein Aufrüsten auf VB 2012 Ultimate (bisher VB 2010 Express) förderte in dieser Hinsicht nichts Neues zu Tage.
    Deshalb meine Frage...Wo finde ich diese Option ?(

    Dankeschön! :)

    Retrospieler schrieb:

    Da mein Programm zwingend einen bestimmten rekursiven mathematischen Algorithmus (welcher immer terminiert) abbilden muss, kommt nur eine Erweiterung des Stack infrage.
    Ich erinnere mich dunkel, dass mehrere Leuts mehrfach und nachdrücklich dich drauf hinwiesen, dass für einen von dir umzusetzenden Algo Rekursion ein fragwürdiger oder eher falscher Ansatz sei.

    Naja, vlt. hast du ja inzwischen einen anneren Algo am Wickel, ansonsten ist vlt. noch immer Rekursion der falsche Ansatz für dein Algo.

    Weiters kann man jeden rekursiven Algo auch Iterativ abbilden.

    ach - nerv - das steht ja sogar im wesentlichen schon in post#2
    Poste einfach mal die auszuwertende Funktion, dann zeigen wir dir eine alternative Herangehensweise. Wie gesagt, es ist häufig sinnlos, etwas auf einem Stapel auszuführen. Jegliche rekursive Funktion kann stattdessen unter Verwendung einer Schleife dargestellt werden. In der Mathematik ist die Rekursive Darstellung ein beliebtes Verfahren, aber in der Programmierung gibt's eben Schleifen.

    Gruß
    ~blaze~
    Das mit der Rekursion war auch nur eine möglichst kurze Hinführung hin zur Frage :wacko:

    Mein Problem momentan ist, dass mein Programm gar nicht erst bis zur Rekursion (die sich in der Regel sehr überschaubar darstellt) kommt, sondern sich schon vorher mit einem Stackoverflow verabschiedet. Hierbei geht es um die iterative Dimensionierung verschiedener technischer Komponenten innerhalb mehrerer Prozeduren (max. Schachtelungstiefe: 3-5) inklusive einiger Dutzend Arrays. Nach einigen Hundert Durchläufen ist halt der Stack voll und das war´s. Eine Umformulierung des Codes würde diesen ca. um den Faktor 5 aufblähen und sehr fehleranfällig (da die einzelnen Bauteile jeweils innerhalb einer eigenen Prozedur mit fallspezifischen Übergabeparametern ausgelegt werden) machen.
    Momentan verfolge ich mit der Anwendung von editbin.exe diesen Ansatz (unten):
    Link

    Momentan krieg ich´s allerdings nicht richtig gehandelt. Nachdem ich editbin.exe und dumpbin.exe zzgl. benötiger .dlls in das Debug-Verzeichnis meines Projekts kopiert hatte, konnte ich tatsächlich mittels cmd die Stacksize der Anwendungs.exe variieren und mittels dumpbin.exe eine Erfolgskontrolle durchführen. Verminder ich die Stacksize, startet das Programm irgendwann gar nichtmehr (logisch), bei einer Erhöhung auf z.B. 5 MB kommen wieder Stackoverflows zutage.

    Da ich das Programm außerdem gerne im Debugger verfolgen möchte, wäre eine explizite Erweiterung des Stack im Code sowieso deutlich besser. Hierzu käme noch folgende Lösung infrage, allerdings weiß ich da nicht, wie sie zu implementieren ist:
    Link

    Wenn da jemand weiß, wie das funktionieren soll (kopieren von MSDN funktioniert nicht, da mich ein "Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis" an der Stelle DTE.Solution anlacht), wäre das spitze :) Merci!
    Es gibt häufig elegante Möglichkeiten, solche Sachen zu managen (z.B. Klassen). Structures sind in diesem Fall nicht wirklich angebracht, da sie ebenfalls auf dem Stapel landen. Wenn du kein Problem damit hast, den Code einzustellen, wäre das evtl. praktischer, irgendwo musst du einen Ansatz haben, ansonsten versuch' mal, einige problematische Codefragmente und den Aufruf oder eine ähnliche Abfolge einzustellen. Aus deinem Beitrag ist bisher noch nicht wirklich hervorgegangen, was das konkrete Problem ist. Wenn sich der Aufruf später außerdem verändert, wird die Rekursion auch bei einem größeren Stapel problematisch.

    Gruß
    ~blaze~
    Danke für den Hinweis...ich bastel mir mal ein Testprogramm um mich mit dem Thema Klassen vertraut zu machen. Das Übertragen des bisherigen Codes auf eine neue Struktur wird vermutlich sehr aufwendig, aber scheint die einzige Option zu sein ;(
    Jenachdem. Es gibt halt keine pauschale Lösung für diese Art von Problemen, daher hatte ich nachgefragt. Klassen an sich sind nicht schwer zu implementieren. Bspw. deine Form ist eine Klasse.
    Der Stack selbst ist eine Art Ablage. Auf ihm werden Zwischenergebnisse, wichtige Werte (z.B. Rücksprungadressen Parameter, Variablen) festgehalten. Jeder Thread erhält so einen Stack mit einer fest definierten Größe (das kann man afaik auf Windows nicht einfach umgehen). Wenn jetzt ein Stapel voll ist, fliegt das Programm. Structures werden auf dem Stapel abgelegt, außer man legt sie explizit im Heap ab. Klar, man könnte jetzt einfach einen Stapel definieren - z.B. als verkettete Liste, da der Heap dynamisch Speicher verwalten kann und somit der Stapel nicht unnötigen Platz wegnimmt, aber das ist eigentlich nicht die Lösung für das Problem, da bei einer größere Datenmenge o.Ä. eben der verwendbare evtl. Speicher nicht ausreicht.

    Gruß
    ~blaze~

    ~blaze~ schrieb:

    aber das ist eigentlich nicht die Lösung für das Problem, da bei einer größere Datenmenge o.Ä. eben der verwendbare evtl. Speicher nicht ausreicht.

    Korrekt. Der TE sollte sich VOR dem Schreiben des Algorithmus Gedanken darüber machen, wie viel Rechenzeit und Speicherplatz die Ausführung desselben erfordert. Man kann z.B. oftmals Rechenzeit gegen Speicherplatz eintauschen (und umgekehrt), indem man den Algorithmus umformuliert. Einfachstes Beispiel dafür: Rekursion vs. Iteration (= Speicher vs. Rechenzeit). Außerdem ist die offensichtliche Berechnung nicht immer die beste bzw. effizienteste. Wenn irgendwo nur ein Zwischenergebnis per "Brute Force" berechnet wird, treibt das die Rechenzeit meist exponentiell in die Höhe.

    Wenn ich am Anfang schon was von "thermodynamischen Berechnungen" lese, dann sollten diese Berechnungen zuerst möglichst effizient formuliert werden. Die verwendete Datenstruktur hat darauf entscheidenden Einfluss - es macht z.B. Sinn, eine Matrix so zu speichern, dass das, was benötigt wird (z.B. Zeilen oder Spalten), in konstanter Zeit geliefert wird (und nicht erst umkopiert werden muss). Allein darüber gibt es sehr dicke Bücher.
    Gruß
    hal2000
    Wie bereits gesagt, wenn es einen (für uns ersichtlichen) Code gäbe, könnte man versuchen diesen dahingehend zu optimieren, dass das Problem nicht mehr auftritt...
    SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

    Weil einfach, einfach zu einfach ist! :D