www.vorhilfe.de
Vorhilfe

Kostenlose Kommunikationsplattform für gegenseitige Hilfestellungen.
Hallo Gast!einloggen | registrieren ]
Startseite · Forum · Wissen · Kurse · Mitglieder · Team · Impressum
Forenbaum
^ Forenbaum
Status Englisch
  Status Grammatik
  Status Lektüre
  Status Korrekturlesen
  Status Übersetzung
  Status Sonstiges (Englisch)

Gezeigt werden alle Foren bis zur Tiefe 2

Navigation
 Startseite...
 Neuerdings beta neu
 Forum...
 vorwissen...
 vorkurse...
 Werkzeuge...
 Nachhilfevermittlung beta...
 Online-Spiele beta
 Suchen
 Verein...
 Impressum
Das Projekt
Server und Internetanbindung werden durch Spenden finanziert.
Organisiert wird das Projekt von unserem Koordinatorenteam.
Hunderte Mitglieder helfen ehrenamtlich in unseren moderierten Foren.
Anbieter der Seite ist der gemeinnützige Verein "Vorhilfe.de e.V.".
Partnerseiten
Weitere Fächer:

Open Source FunktionenplotterFunkyPlot: Kostenloser und quelloffener Funktionenplotter für Linux und andere Betriebssysteme
Forum "Softwaretechnik und Programmierung" - JAVA - Ruhezustand berechnen
JAVA - Ruhezustand berechnen < Softwaretechnik+Pro < Praktische Inform. < Hochschule < Informatik < Vorhilfe
Ansicht: [ geschachtelt ] | ^ Forum "Softwaretechnik und Programmierung"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien

JAVA - Ruhezustand berechnen: Frage (beantwortet)
Status: (Frage) beantwortet Status 
Datum: 02:02 Di 15.05.2007
Autor: Chochalski

Aufgabe
StackOverflowError!!!

Glück Auf!

Ich habe folgendes Problem:
Bei der Implementierung eines LogikSimulators kann ich den Ruhezustand einer Schaltung nicht berechnen. Der Grund dafuer:
StackOverflowError.

Ich habe zwar herausbekommen, dass dies ein Speicherproblem darstellt, aber wie das zu lösen ist,...?
Googleergebnisse brachten nur, dass das Stack zu klein ist (???)
(An dieser Stelle sollte ich vielleicht auch sagen, dass ich Java-Newbie bin).

Das Problem taucht natuerlich nur bei Rueckkopplungen auf.
Die Berechnung des Ruhezustandes hab ich realisiert, indem ich die betreffenden Gatter bei der Berechnung des Ausganges (verzoegerungsfrei) einfach mitzaehlen lasse und bei einer Zahl aussteigen lasse.

Das funktioniert bei kleinen Schaltungen recht gut, aber bei komplexen Schaltungen geht das nicht mehr.
Ich habe mal getestet, wie oft ich den Ausgang eines einzigen Nor-Gatters
(Input a,b, Output b) berechnen kann: ca. 1000mal
Bei einer etwas groesseren Schaltung mit einigen Rueckkopplungen sind es nur noch 140mal, obwohl ich ca. 5000mal bräuchte.

Ist zwar alles sehr miserabel beschrieben, aber ich hoffe mal, Ihr versteht das Problem.

mfg
Chochalski


        
Bezug
JAVA - Ruhezustand berechnen: Antwort
Status: (Antwort) fertig Status 
Datum: 10:30 Di 15.05.2007
Autor: Frank05


> Ich habe zwar herausbekommen, dass dies ein Speicherproblem
> darstellt, aber wie das zu lösen ist,...?
>  Googleergebnisse brachten nur, dass das Stack zu klein ist
> (???)
>  (An dieser Stelle sollte ich vielleicht auch sagen, dass
> ich Java-Newbie bin).

Ich schließe mal aus deiner Beschreibung und der Fehlermeldung, dass deine Implementierung rekursiv ist.
Du solltest dich mal mit []Rekursion vertrauter machen. Dein Problem hat nicht mit Java direkt zu tun, sondern damit, dass bei rekursiven Funktionen generell immer ein Problem mit der Stacktiefe auftaucht, weil bei jedem rekursiven Aufruf ein neuer Stackeintrag gemacht werden muss.
Fazit: Eine 1000-teilige Schaltung mit rekursiven Funktionen inklusive Rückkopplung einfach mal so berechnen zu wollen ist von vorne herein zum Scheitern verurteilt.

Du musst also entweder einen Weg finden die Anzahl der rekursiven Aufrufe zu reduzieren (was aber nur einer Behandlung der Symptome entspricht), oder du implementierst das Ganze nochmal iterativ.

Bezug
                
Bezug
JAVA - Ruhezustand berechnen: Frage (beantwortet)
Status: (Frage) beantwortet Status 
Datum: 13:11 Di 15.05.2007
Autor: Chochalski

Danke, ich versteh zwar wie du das meinst, ABER: ich hab gar keine Ahnung wie ich das umsetzen kann.
Den einzigen Loesungsansatz, den ich mir vorstellen kann ist, dass das Gatter mitzaehlt, wie oft es seinen ausgang aendert.
Hat es den Ausgang oft genug geaendert, dann soll es bitte aufhoeren.
Und genau da muss ich ja bei jedem Aufruf kontrollieren, ob das der Fall ist
um die Endlosschleife zu verlassen.
Der andere Ansatz ist im Prinzip der selbe, nur da lasse ich zaehlen, wie oft sich eine Signalleitung aendert...
Ich gehe mal davon aus, dass der Ansatz richtig ist, aber die Umsetzung sehr schlecht ist.

Aus den oben aufgefuehrten Link konnte ich ich fuer iterative Varianten folgende Aenderung realisieren (Obwohl ich nicht ueberzeugt bin, dass diese Loesung iterativ ist, meines erachtens stellt diese Variante kaum eine Veraenderung dar).
kurze Einfuerung: Ich habe eine Superklasse Gate, aus der ich alle geforderten Gatter ableite. In Gate habe ich also

protected final static int maxBerechnung = 5000; //so oft darf das Gatter berechnen
protected int aktBerechnung;  //so oft wurde berechnet


Wenn ich jetzt z.B. den Ausgang eines Buffers berechnen will, dann solange bis es nicht mehr notwendig ist. Die Methode sieht also so aus:

public void ausgangBerechnen(...){
   while (super.maxBerechnung > super.aktBerechnung) {
      super.aktBerechnung++;
      ...
   }
}


Ich kann also so auch nur recht kleine maxBerechen fahren.
Koennte mir einer bitte einen anderen ansatz empfehlen?
bzw. wie kann ich diese Kontrolle, ob ich oft genug berechnet habe iterativ durchfuehren?

mfg
Chochalski

Bezug
                        
Bezug
JAVA - Ruhezustand berechnen: Antwort
Status: (Antwort) fertig Status 
Datum: 17:51 Di 15.05.2007
Autor: Frank05


> Aus den oben aufgefuehrten Link konnte ich ich fuer
> iterative Varianten folgende Aenderung realisieren (Obwohl
> ich nicht ueberzeugt bin, dass diese Loesung iterativ ist,
> meines erachtens stellt diese Variante kaum eine
> Veraenderung dar).

Der Code, den du hier angegeben hast, ist auch nicht relevant für die Entscheidung ob iterativ oder rekursiv.

>  kurze Einfuerung: Ich habe eine Superklasse Gate, aus der
> ich alle geforderten Gatter ableite. In Gate habe ich also
>  
> protected final static int maxBerechnung = 5000; //so oft
> darf das Gatter berechnen
> protected int aktBerechnung;  //so oft wurde berechnet
>  
> Wenn ich jetzt z.B. den Ausgang eines Buffers berechnen
> will, dann solange bis es nicht mehr notwendig ist. Die
> Methode sieht also so aus:
>  
> public void ausgangBerechnen(...){
>     while (super.maxBerechnung > super.aktBerechnung) {
>        super.aktBerechnung++;
>        ...
>     }
> }

Die entscheidende Frage ist nun, ob ein weiterer Aufruf von ausgangBerechnen(..) in dem Teil mit dem ... vorkommt. So wie das hier steht gibt es nämlich keinen StackOverflow. Das ist nur eine simple Schleife und wird für sich genommen keinerlei Probleme bereiten.

> Ich kann also so auch nur recht kleine maxBerechen fahren.
>  Koennte mir einer bitte einen anderen ansatz empfehlen?
>  bzw. wie kann ich diese Kontrolle, ob ich oft genug
> berechnet habe iterativ durchfuehren?

Wie wäre es mit etwas in der folgenden Art:
1:
2: while (++berechnungsSchritt <= maxBerechnungen && !keine_aenderung) {
3:   keine_aenderung = true;
4:   /* Update des kompletten Netzes um einen Schritt,
5:    also neues Ergebnis für jedes Gatter hier auf einen
6:    Schlag berechnen. Wenn sich etwas geändert hat wird
7:    keine_aenderung auf false gesetzt. */
8: }


Bezug
Ansicht: [ geschachtelt ] | ^ Forum "Softwaretechnik und Programmierung"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien


^ Seitenanfang ^
www.englischraum.de
[ Startseite | Forum | Wissen | Kurse | Mitglieder | Team | Impressum ]