Calocybe: Rekursive Aufrufe

Beitrag lesen

Hi Andrea!

Moin? Nachmittags um 5? Mir scheint, Du hast einen reichlich verdrehten Tagesablauf ;-)

Ja klar! Morgen ist dann wenn man aufsteht! Oder wann ist das bei Dir? ;-)

Globale_Variable;

function ticker {

»»  Initialisierungen;
»»  Ticker_Ausgabe;

»»  setTimeout(ticker, 100);

}

Eigentlich dürfte imho bei setTimeout(...) ja gar kein Stack-Speicher verbraucht werden, weil die Funktion nach der gewissen Zeit vom Event-Handler anstatt von sich selbst neu aufgerufen wird - d.h. beim vorigen Aufruf wurde die Funktion normal beendet.

Genau, es sei denn man setzt das Intervall kleiner als die Zeit, die zum Ausfuehren der Funktion benoetigt wird. Was dann passiert, ist wohl auch browserabhaengig. (Spekulationen darueber lass ich jetzt mal sein. Wenn man sowas macht, muss man sich sowieso erstmal um ein Parallelitaetsproblem kuemmern, ich meine, dass da nichts schief geht.)

Aha. Somit ist mein 'rekursiver' Aufruf gar nicht wirklich rekursiv?
Dann haette ich mir die Sache mit den'globalen Variablen schenken koennen?

Gerade die lokalen Variablen sollen doch den Stack verbrauchen! Ansonsten muss man doch nur die "Ruecksprungadresse" speichern (um es mit Mitteln richtiger Programmiersprachen auszudruecken). Und da kannst Du auf einen Ueberlauf ziemlich lange warten, selbst wenn der (virtuelle) Stack begrenzt ist. (Virtuell weil dies ja nur vom Prinzip her soetwas wie einen Stack darstellt, aber nichts mit dem Stack zu tun hat, den z.B. das Browser-Programm selber verwendet. Uebrigens wird unter Windows NT der (echte) Stack vom Betriebssystem dynamisch vergroessert, wenn er nicht ausreichen sollte.)

Woher kommt dann der immense Speicherverbrauch?

setTimeout() und setInterval() haben beim Netscape for Win ein ziemlich grosses Memory-Leak. Man sollte die Funktionen daher nur einsetzen, wenn es unbedingt sein muss, und dann mit moglichst grossen Intervallen. Je kleiner das Intervall ist, um so eher faengt die Platte an zu rattern...  Als Geocities noch sein Logo in der rechten unteren Ecke hatte, hatten sie es mit einem Intervall von 0.1 sec immer wieder an die richtige Position gesetzt, da hat man von dem Memory-Leak praktisch nix gemerkt. Mich wundert, dass Du in der Funktion oben auch die 100ms verwendest. So hoch sollte der Speicherverbrauch dadurch nicht sein. Ausserdem duerfte da kaum der Eindruck einer Bewegung entstehen (10 Schritte pro Sekunde, mindestens 25 sollten es sein).

Nun bleibt also die Frage - laeuft der (virtuelle) Stack irgendwann ueber? Also wenn ich einen JS-Interpreter schreiben muesste, wuerde ich einfach immer, wenn ich wieder Stack brauche, weiteren Speicher "ziehen". Fuer mein Interpreterprogramm ist das ja kein Stack, sondern normaler Arbeitsspeicher, den man einfach allokieren kann. Insofern sollte der virtuelle Stack des JavaScripts nur durch die Resourcen der ausfuehrenden Maschine begrenzt sein. Allerdings kann man darueber nachdenken, ob man denn nicht eine Obergrenze einbauen sollte, denn wenn ein JS 50 MB an Stack verbraet, dann wuerde ich schonmal davon ausgehen, dass es einfach ziellos im Kreis laeuft, sprich: abgestuerzt ist. (Manche Leute glauben, wenn ein Computer abgestuerzt ist, tut er nichts mehr, aber das Gegenteil ist der Fall. Er tut sogar besonders viel, laeuft meist irgendwie im Kreis, rechnet irgendwelche Dinge, ohne aus der Schleife herauszukommen. Deshalb kann das Programm dann keine Eingaben mehr entgegennehmen oder reagieren und es entsteht der Eindruck, es tut nichts mehr.) Bei Rekursionstiefe 100 wuerde ich diese Grenze allerdings noch lange nicht ziehen.

Und "Muss ich mir sogar bei JS Gedanken um den Stack machen?" Also ich finde, um die Resourcen sollte man sich immer Gedanken machen. Aber der Speicherausbau moderner Computer sollte ein bisschen Rekursion eigentlich locker verkraften.

Stefan hat geschrieben

Rekursive Funktionsaufrufe sollte man daher unbedingt in ein window.setTimeOut("Funktion()",100) verpacken

Naja, fuer mich soll eine rekursive Funktion auch irgendwann ein Ergebnis liefern (z.B. Primzahlenzerlegung oder Fakultaet berechnen (ich weiss, geht beides auch ohne Rekursion und effektiver)), nur das wird mit setTimout kaum moeglich sein. Wenn ich das jetzt richtig ueberblicke, macht Rekursion sowieso keinen Sinn, wenn man setTimout() verwenden kann.

Calocybe - hat heute einfach keinen Bock zum Arbeiten *mmpf*