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 Übung 26 – Das erste kleine Java Spiel

Java Übung Zahlenraten

In dieser Java Übung geht es darum ein kleines Java-Spiel zu erstellen. Und zwar Zahlen raten. Was kannst du dir darunter vorstellen? Du gibst einen bestimmten Wertebereich an. Zum Beispiel 0 bis 100. Und das Java Programm erstellt eine Zufallszahl in diesem Bereich. Dann fordert dich das Programm auf, die Zahl zu raten. Du gibst […]

Der bedeutende Unterschied zwischen Klassenvariablen und Instanzvariablen

Java Klassenvariablen

Bei der Java Programmierung unterscheidet man drei Arten von Variablen. Als erste Gruppe sind die lokalen Variablen zu nennen. Auf diese gehe ich in einem separaten Artikel ein. Mich interessieren die zwei anderen Variablentypen. Zum einen existieren Klassenvariablen. Und dann sind da noch die Instanzvariablen. Wo liegt der Unterschied? Instanzvariablen stehen einem Objekt zur Verfügung. […]

Von Java Klassen zum Java Programm – Der Programmstart

Java Klassen ausführen

In den letzten Beiträgen hast du gelernt, wie Java Klassen erstellt werden und aufgebaut sind. In diesem Beitrag geht es um den Programmstart. Ich will dir zeigen, was nötig ist, dass du ein Java Programm ausführen kannst. Und ich zeige dir außerdem, wie du eine Startklasse in einem x-beliebigen Javaprogramm anlegst. Wie auch schon zuvor, […]

So unterstützen dich Java Vererbungstabellen beim Entwurf

Java Vererbungstabellen

Bei der Java Vererbung gibt es zwei Klassenarten bzw. -stufen. Die Superklassen, welche einen allgemeinen Typen darstellen Und die spezielleren Unterklassen, welche die Superklasse um bestimmte Funktionen erweitern. Jetzt ist dieses ganze „Der-erbt-von-dem-Konzept“ mitunter sehr schwierig darzustellen. Zum Beispiel in einem Werkzeugkoffer. In einem Werkzeugkoffer befinden sich sämtliche Werkzeuge, von Säge bis Bohrmaschine. Wie machst […]

Nutze die Fernbedienung für deine Java Objekte

Auf Java Objekte greifst du mit einer Art Fernsteuerung zu. Diese bezeichnet man als Referenz oder als Verweis. Und diese Referenzvariablen möchte ich dir jetzt einmal vorstellen. Doch bevor wir loslegen, lass mich noch ein paar Dinge loswerden. 🙂 Ich habe es ja schon einmal in einem früheren Beitrag erwähnt. Java unterscheidet zwischen primitiven und […]

Java Übung 17: Char-Zeichen mit For-Schleife

Java Übung Char Zeichen For Schleife

In dieser Java Übung werden wir uns die Zeichen des Character Datentypen näher anschauen. Die einzelnen Zeichen sollen auf der Konsole ausgegeben werden. Und wie? Das ganze sollst du mit einer For Schleife machen. Erstelle deshalb eine Klasse „CharZeichen“. In dieser Klasse implementierst du dann eine Klassenmethode, namens „gibZeichen“. Und im Methodenrumpf durchläuft eine For-Schleife […]

Verwalte deine Java Klassen in packages

java klassen verwalten

Es macht durchaus Sinn deine Java Klassen in verschiedenen Paketen zu organisieren. Wieso? Es sprechen mehrere Gründe dafür: Du kannst doppelte Klassennamen verwenden Du kannst deinen Code oder deine Klassen inhaltlich trennen Du kannst Hierarchien abbilden. Und genau um diese Dinge geht es in diesem Beitrag

Das Java Leben ist einfacher mit For-Schleife

Java For Schleife Aufbau

In einem anderen Artikeln habe ich bereits über Schleifen in Java gesprochen. In diesem Artikel möchte ich dir eine ganz besondere Schleife vorstellen. Warum ist diese so toll? Sie hat einen integrierten Schleifenzähler. Die Schleife zählt also bei jedem Durchlauf automatisch mit. Aber dazu gleich mehr…. Lass uns einmal so eine For Schleife anlegen.