Skip to main content

Beim Aufruf werden Java Methoden auf dem Stack gestapelt

Java Methoden werden beim Aufruf gestapelt.
Und jedes Element auf dem Stapel nimmt Speicherplatz weg.

Und manchmal ist es so, dass der Stapel richtig hoch wird und dann….

Ja was passiert eigentlich dann?

Betrachten wir einmal ein Computerspiel.
Irgendeines. In diesem Computerspiel gibt es Vögel, welche abgeschossen werden sollen.

Was bedeutet das denn genau?

  • Beim jedem Schuss ist ein bisschen Speicherplatz weg?
  • Oder bei jeder Mausbewegung ist wieder ein Speicherblock weg?
  • Was passiert, wenn eine Methode eine andere aufruft – Ist dann gleich doppelter Speicherplatz weg?

Ich sage dir:
In einem kleinen Programm, denkst du über so etwas gar nicht nach.
Denn es hat kaum bemerkenswerte Auswirkungen.

Aber was ist in einem großen Spiel, wo sekündlich richtig viele Aktionen durchlaufen.
Reserviert Java dann nicht immer mehr Speicher?

Also dann.
Wie kannst du das Speicherproblem für diese Methoden lösen?
Oder löst es Java allein?
Was ist dabei zu beachten?

Na Interesse?
Dann lies diesen Artikel.

Java Methoden und lokale Variablen findest du auf dem Stack.

Der Stack ist die Speicherverwaltung für Java Methoden und deren lokale Variablen.
Bleiben wir doch beim Spiel und bei den Vögeln.

Nehmen wir an, dass es im Spiel drei Methoden gibt.

  • fliegen(): Diese Methode gibt eine Information, dass der Vogel fliegt.
  • getroffenSein(): Der Vogel wurde getroffen und ein Geräusch ertönt.
  • abstürzen(): Nachdem der Vogel getroffen wurde, stürzt dieser ab.

Beginnen wir mit der Methode fliegen().
Sobald diese aufgerufen wird, landet sie auf dem Stack.

Am Ende der Methode, bei der schließenden Klammer, verschwindet diese aus dem Stack.
Der Speicherplatz wird somit freigegeben.


public class VogelSpiel {
 
void fliegen(int flugGeschwindigkeit) {
System.out.println("Der Vogel fliegt mit einer Geschwindigkeit von " + flugGeschwindigkeit);
} // fliegt vom Stack
 
public static void main(String[] args) {
VogelSpiel vogelEins = new VogelSpiel();
vogelEins.fliegen(2);
}
}

Was ist mit der lokalen Variable „flugGeschwindigkeit“?
Lokale Variablen werden am Ende von Java Methoden ebenfalls zerstört.
Denn diese Variable gehört schließlich zur Methode.

Und somit wird diese genauso behandelt, wie die Methode selbst.
Sie fliegt also runter vom Stack.

Und wenn du andere Methoden aufrufst, dann werden diese schön nacheinander auf dem Stack geschoben und wieder heruntergeschmissen.

Im Beispiel wird zuerst die fliegen() Methode, mitsamt der lokalen Variablen, auf den Stack geschoben.
Am Ende der Methode (geschweifte Klammer) wird diese vom Stack herunter geschoben und macht Platz.

Sie könnte Platz machen für die „getroffenSein()“ Methode.
Jetzt ist ihr großer Auftritt. 🙂
Und auch diese existiert nur bis zum Ende des Methodenausdrucks (Klammer).

Aber was passiert, wenn eine Methode die andere aufruft?

Java Methoden können gestapelt werden.

Angenommen die Methode „fliegen ()“, ruft die Methode „getroffenSein ()“ auf.
Und „getroffenSein ()“ ruft die nächste Java Methode auf.

Das Ganze könnte so aussehen:


public class VogelSpiel {
 
void fliegen(int flugGeschwindigkeit) { 
System.out.println("Der Vogel fliegt mit einer Geschwindigkeit von " + flugGeschwindigkeit);
getroffenSein("Bing ÄÄÄHHHH"); //Java Methode getroffenSein wird aufgerufen
} 
 
void getroffenSein(String ton){ 
System.out.println(ton);
abstuerzen(22); //GetroffenSein ruft die nächste Java Methode auf
} 
 
void abstuerzen(int absturzgeschwindeigkeit){
System.out.println("Vogel stürzt mit einer Geschw. von "+absturzgeschwindeigkeit+" zu Boden.");
}
 
public static void main(String[] args) {
VogelSpiel vogelEins = new VogelSpiel();
vogelEins.fliegen(2);
}
}

Und jetzt beginnt das Spiel beim Fliegen.
Und beim Fliegen wird der Vogel getroffen.
Und er stürzt ab.

Ungewöhnlich, aber während des Absturzes fliegt der Vogel noch. 🙂
Da die Methode fliegen() noch nicht geschlossen wurde.

Stell dir das Ganze als eine Art Stapel vor.
Speicherverwaltung hat etwas mit Verwaltung zu tun.
Und in jeder Verwaltung gibt es Akten- oder Dokumentenstapel.

Und auf dem Stack existieren jetzt vier Methoden (mit main-Methode) in einem Stapel.

Java Methoden Stapel

Ganz oben liegt die aktuellste Methode.
Dies ist die letzte Methode, welche aufgerufen wurde.
Darunter die „getroffenSein()“ Methode usw.

Wenn jetzt diese Java Methoden geschlossen werden, verschwinden diese von oben nach unten aus dem Stapel.
Zuerst wird die „abstuerzen()“ Methode geschlossen und es wird Speicher frei gemacht.

Da die „abstuerzen()“ Methode innerhalb des Methodenrumpfes der „getroffenSein()“ Methode aufgerufen wurde, existiert die „getroffenSein()“ Methode einfach länger auf dem Stack.

Und da die „getroffenSein()“ Methode innerhalb der „fliegen()“ Methode aufgerufen wurde, existiert die „fliegen()“ Methode wiederum länger.

Du kannst somit sagen:
Wenn der Vogel abstürzt – läuft immer noch die „getroffenSein()“ Methode und die „fliegen()“ Methode.

Somit fliegt der Vogel noch beim Absturz. 🙂

Bauen wir einen Stapel Java Methoden bis in den Himmel.

Was ist, wenn die letzte Methode „abstuerzen()“ die erste Methode „fliegen()“ aufruft.

Somit würde die fliegen() Methode starten.
Diese wiederum ruft die nächste Java Methode, „getroffenSein()“, auf.

„GetroffenSein()“ ruft dann „abstuerzen()“ auf.
Und „abstuerzen“ ruft wieder „fliegen()“ auf.

Java Methoden Stack

Eine Endlosschleife.
Cool. Lass es uns ausprobieren.

So würde der Java Code dazu aussehen:


public class VogelSpiel {

	void fliegen(int flugGeschwindigkeit) {
		System.out.println("Der Vogel fliegt mit einer Geschwindigkeit von " + flugGeschwindigkeit);
		getroffenSein("Bing ÄÄÄHHHH"); 
	}

	void getroffenSein(String ton) {
		System.out.println(ton);
		abstuerzen(22); 
	}

	void abstuerzen(int absturzgeschwindeigkeit) {
		System.out.println("Vogel stürzt mit einer Geschw. von " + absturzgeschwindeigkeit + " zu Boden.");
		fliegen(22); //abstürzen ruft jetzt wieder fliegen auf
	}

	public static void main(String[] args) {
		VogelSpiel vogelEins = new VogelSpiel();
		vogelEins.fliegen(2);
	}
}

Klicke auf „Run“ und schau selbst nach, was passiert.

Java Methoden lassen sich nicht unendlich stapeln. Es kommt zum StackOverFlow.

Na hast du auf „Run“ geklickt?

Dann wird dir die Fehlermeldung StackOverFlow aufgefallen sein.
Blöd, oder? 🙂

Es ist eigentlich logisch.
Stell dir vor, du hast ausversehen so einen endlosen Stapel gebaut.
Alle Java Methoden brauchen Speicher.
Und die lokalen Variablen innerhalb der Methoden ebenfalls.

Klar, dass der Speicher nicht unendlich ist.
Und Java schützt dein Programm mit dieser Exception oder Fehlermeldung.
Es ist somit ein ganz nützliches Feature, welches Java bereitstellt.

StackOverFlow bedeutet somit:
Stapel voll. Stapel fließt über. Mehr geht nicht. Abbruch.

So was bleibt noch zu sagen?

Die Main Methode liegt natürlich auch auf dem Stapel

Diese liegt ganz unten.

Diese lasse ich aber außen vor.
Denn innerhalb der Main-Methode wurde ebenfalls eine lokale Variable, „vogelEins“, angelegt.
Diese verweist aber auf ein Objekt.

Und Objekte haben eine andere Speicherverwaltung als Java Methoden.
Die Objektverwaltung findet auf dem sogenannten Heap statt.
Und das ist ein eigenes Kapitel.

Zusammenfassung:

  • Java Methoden werden auf dem Stack gestapelt.
  • Eine Methode beginnt bei ihrer öffnenden und endet bei ihrer schließenden Klammer.
    In dieser Zeit liegt sie auf dem Stack.
  • Ruft eine Methode eine andere Methode auf, werden die Methoden gestapelt.
  • Wird der Stapel zu hoch oder geht ins Unendliche kommt es zum StackOverFlow.
  • Java Objekte werden speicherintern anders behandelt, als Java Methoden.
    Methoden liegen auf dem Stack und Objekte leben auf dem Heap.

Ähnliche Beiträge

Java Objekte leben auf dem Heap

Java-Objekte-Heap

Java hat eine interne Speicherverwaltung. Eigentlich ist es nicht nur eine. Es sind mehrere.   Uns interessieren nur zwei. Methoden und lokale Variablen werden auf dem Stack verwaltet. Und die Speicherverwaltung für Java Objekte und den Instanzvariablen findet auf dem Heap statt.   Ja wieso braucht Java eigentlich zwei Speichersysteme?   Es ist ganz einfach. […]

Java Exklusives Oder – So nutzt du den Xor Operator

Java exklusives oder

In diesem Beitrag möchte ich dir den Xor Operator von Java vorstellen. Dieser Operator wird auch als ausschließendes oder exklusives Oder bezeichnet. Ein Beispiel: Was wilst du heute zum Mittag essen: Fleisch oder Fisch? Auf diese Frage gibt es nur eine Antwort. Es ist entweder Fisch oder Fleisch. Niemals beides. Das Eine schließt das andere […]

Ende vom Java Blog?

Falls du hier schon länger dabei bist, wird dir aufgefallen sein – dass kaum noch Beiträge veröffentlicht werden. Das tut mir wirklich leid und dafür möchte ich mich auch entschuldigen. Ich weiß, dass Einige unter Euch den Java-Blog wirklich lieben. Aber es ist verdammt schwierig so ein aufwendiges Thema – stilvoll, unterhaltend und methodisch umzusetzen. […]

So kannst du Java Arrays mit for Schleife füllen und auslesen

Java Arrays For Schleife

Wir haben in einem anderen Beitrag bereits über Java Arrays gesprochen. So ein Array speichert Zahlen, Texte oder Objekte in eine Art Liste. Und dann kannst du ganz bequem über den Index das Array füllen und die bereits enthaltenen Werte abrufen. Ganz bequem? So, wie ich dich aus dem letzten Beitrag entlassen habe, war das […]

So kannst du ein Java Programm starten und Argumente übergeben

Um ein Java Programm starten zu können, benötigst du immer die main-Methode. Das Programm startet immer genau an dieser Stelle. Alle lokalen Variablen, welche du in der Main Methode anlegst, kannst du dann im Programm nutzen. Auch alle Methoden, welche du innerhalb des Methodenrumpfes der main-Methode aufrust, werden ausgeführt. Was ist aber vor der main-Methode. […]

Das Java Vererbung Konzept in einem Rollenspiel

Java ist eine objektorientierte Programmiersprache. Und das bedeutet nicht nur, dass du Objekte einer Java Klasse erzeugen kannst. Es bedeutet auch, dass Java Klassen von anderen Klassen erben können. Wieso das Ganze? Stell dir einmal ein Rollenspiel vor. Wie würdest du ein Rollenspiel entwerfen? In einem Rollenspiel gibt es magische Gegenstände. Zauberringe, Zauberstäbe, welche bei […]

Die vier verschiedenen Zahlensysteme in der Java Programmierung

Java Zahlensysteme

Java Zahlensysteme – Was soll das? In sämtlichen Programmiersprachen werden Zahlen in Variablen abgespeichert. Wenn du dir die einzelnen primitiven Datentypen in Java einmal anschaust – wirst du feststellen – dass die Masse der Datentypen Zahlen annehmen und speichern können. Zahlen und die Mathematik dahinter spielen in der Programmierung eine sehr große Rolle. Ganz am […]