Stack...

izoards

Bekanntes Mitglied
Hallo,

Eine Frage, wenn ich z.B. in einer Endlosschleife, jeweils immer wieder neue Variablen definiere, gibt das irgendwann ein Problem?
Also wird der Stack damit belastet und kommt es dann irgendwann zur Laufzeit zu Problemen?
Danke für die Hilfe
 

KonradN

Super-Moderator
Mitarbeiter
Hallo,

Eine Frage, wenn ich z.B. in einer Endlosschleife, jeweils immer wieder neue Variablen definiere, gibt das irgendwann ein Problem?
Also wird der Stack damit belastet und kommt es dann irgendwann zur Laufzeit zu Problemen?
Danke für die Hilfe
Also eine Variable in einer Endlosschleife zu deklarieren führt zu keinen Problemen. Eine Endlosschleife arbeitet auch nicht mit dem Stack. Die lokalen Variablen, die Du in der Endlosschleife nutzt, sind ja in einer Methode und zu dieser gehören diese.

Wenn Du mit definieren eine Zuweisung meinst, dann kann es prinzipiell problematisch sein, so Du hier immer neuen Speicher belegst (z.B. durch die Erzeugung von neuen Instanzen). So diese noch referenziert werden (z.B. in einer Liste), dann ist irgendwann der Speicher voll. Wenn Du die nicht mehr Referenzierst, dann muss der Speicher aufgeräumt werden - das macht der GC und das kann in bestimmten Situationen durchaus problematisch sein.
 

izoards

Bekanntes Mitglied
Hallo Konrad, herzlichen Dank für die rasche und immer sehr nette und kompetente Rückmeldung.
Mit definieren meine ich z.B. das:

Java:
int answer = communication.waitForConfirmation("commandXY", timeout * 1000);

oder auch das:

Java:
BufferedReader bin = new BufferedReader(
                                new InputStreamReader(none.openStream()));

Edit: Gibt es eine Möglichkeit das zu beobachten? Also ob der Stack dauernd wächst? Kann das mittels Task Manager Memory Auslastung gemacht werden?
 

Jw456

Top Contributor
Das erste sollte keine Probleme machen. Ist ja statisch.

Das zweite ist dynamisch (new) könnte irgendwann, wenn nicht freigeben wird, den Speicher füllen

ps wird wohl nicht passiren da BufferedReader das sicher begrenzen wird.
 

KonradN

Super-Moderator
Mitarbeiter
Der erste Fall ist einfach: Du hast eine "value type" Variable - da wird also nur ein Wert gespeichert. Es wird also eine Methode aufgerufen mit allem drum und dran: Auf den Stack kommt Platz für die Rückgabe, die Rücksprungadresse, die beiden parameter, die lokalen Variablen der Methode. Dann läuft die Methode ab und am Ende wird alles vom Stack genommen und mit dem letzten Schritt die Rückgabe vom Stack in der Variablen gespeichert. Das ist also absolut neutral.

Der Zweite Fall ist kritischer. Hier erzeugst Du neue Instanzen (BufferedReader, InputStreamReader und ein InputStream, der von openStream zurück kommt). So Du diese nur in der Variablen bin referenzierst, ist es egal - der GC kann das sehr gut erkennen und verarbeiten. (Es gibt diverse Algorithmen für GCs daher gehe ich da nicht weiter drauf ein - aber klar ist: Das ist ein typischer Fall, wie es ihn sehr oft gibt. Das muss also ein GC gut beherrschen!)
Problematisch ist hier aber, dass auch Ressourcen geöffnet werden, die ggf. geschlossen werden sollten. Da wäre ein try-with-resources der richtige Ansatz. (Oder halt sicher stellen, dass immer ein close() aufgerufen wird!)
 

izoards

Bekanntes Mitglied
Problematisch ist hier aber, dass auch Ressourcen geöffnet werden, die ggf. geschlossen werden sollten. Da wäre ein try-with-resources der richtige Ansatz. (Oder halt sicher stellen, dass immer ein close() aufgerufen wird!)

Macht es denn Sinn, in einer Endlosschleife, jeweils immer wieder zu schliessen close()? Um dann bald wieder zu öffnen... (ca. alle sekunden)
Oder wäre es besser, wenn ich kein (new) in der Schleife habe, und dann erst schliesse, wenn die Schleife doch mal verlassen wird. (Beim schliessen des Programmes)
 

KonradN

Super-Moderator
Mitarbeiter
Macht es denn Sinn, in einer Endlosschleife, jeweils immer wieder zu schliessen close()? Um dann bald wieder zu öffnen... (ca. alle sekunden)
Oder wäre es besser, wenn ich kein (new) in der Schleife habe, und dann erst schliesse, wenn die Schleife doch mal verlassen wird. (Beim schliessen des Programmes)
Durch das new hast du ein ständiges Öffnen. Es sind immer neue Reader. Was wir nicht sehen, ist der Stream - wenn dies immer der gleiche Stream ist und nicht immer ein neu geöffneter, dann hast Du ggf. ein Problem. Denn wenn der Reader geschlossen wird, dann wird auch der zugrunde liegende Stream geschlossen. So ein Pattern, dass ein Stream immer wieder nach außen gegeben wird, ist somit zumindest sehr fehleranfällig.

Und man muss auch aufpassen: Du hast einen BufferedReader - der kann also auch etwas zwischenspeichern. Wenn Du aus einem Stream mehrfach etwas lesen willst, dann bedeutet dies, dass Daten verloren gehen könnten. Fiktives Beispiel (Das ist so nicht!): Angenommen der BufferedReader liest immer 2 Zeilen auf einmal - auch wenn Du nur 1 Zeile brauchst. Das sieht dann so aus:
Stream hat etwas wie
a
b
c
d

Unser BufferedReader würde beim Lesen der ersten Zeile gleich a und b lesen und das a weiter geben. Beim lesen der nächsten Zeile hätte der BufferedReader diese schon und könnte das b zurück geben.

Nun machen wir die Schleife immer mit neuen BufferedReadern (von unserem spezial BufferedReader!)

Erster Schleifendurchlauf: Stream hat noch a-d, erster BufferedReader soll eine Zeile lesen, liest a und b. Gibt b zurück.
Nächster Schleifendurchlauf: Stream hat nur noch c-d, erster BufferedReader hätte im Buffer noch das b, wir machen aber ein neuen BufferedReader und lesen damit dann eine Zeile: Er liest c und d und gibt c zurück.
==> Es gehen also Daten verloren!

Daher ist die typische Vorgehensweise immer:
  • Ich erzeuge den Reader
  • Dann gehe ich in der Schleife diesen Reader durch, bis ich alles gelesen habe
  • dann am Ende schließe ich den Reader

Aber es hängt immer an den Anforderungen - wenn ich eine Datei mit ganz vielen Zeilen habe und ich will diese immer wieder durchgehen: Dann habe ich natürlich eine Schleife, in der die Datei geöffnet wird, der Inhalt der Datei ausgewertet und dann die Datei geschlossen wird. Und dann wird das immer wieder erneut gemacht. Sowas ist denkbar. Aber das ist halt kein typischer Anwendungsfall sondern ein sehr spezieller ...

Aber kommen wir zurück zu Deinem Anwendungsfall: Was macht denn die Methode openStream? Vom Namen her, wird ja ein Stream geöffnet. Es kommt also immer ein neues Stream zurück. Das wäre also so durchaus ok - Beispiel wäre: In einer Schleife gehst Du alle Dateien eines Verzeichnisses durch und verarbeitest diese. Etwas in der Art.
 

izoards

Bekanntes Mitglied
Also der openStream macht eigentlich nur einen http - Befehl auf einem lokal laufenden Programm

Bspsw:

Java:
URL off = new URL("http://localhost:55555/command?setcolors=off");
 

KonradN

Super-Moderator
Mitarbeiter
Das sieht dann doch vernünftig aus. Bei dem Code sehe ich so erst einmal kein Problem. Das try with resources sollte angewendet werden, aber auch ohne dürfte der Code problemlos so laufen - da wird dann der GC halt das Aufräumen erledigen (nicht schön aber das ist ja nicht das eigentliche Thema).
 

izoards

Bekanntes Mitglied
Ich muss hier doch nochmals nachfragen...
Habe jetzt bin.close() jeweils noch hinzugefügt... (Um sicherer zu sein)

Java:
BufferedReader bin = new BufferedReader(
                                new InputStreamReader(none.openStream()));

Wenn ich das Programm jedoch laufen lasse und die Arbeitsspeicher Auslastung im Task Manager beobachte, steigt dieser langsam, aber stetig an.

Das ist doch ein Zeichen, dass irgendwas nicht sauber ist, richtig? 🤦‍♂️
 

KonradN

Super-Moderator
Mitarbeiter
Das ist doch ein Zeichen, dass irgendwas nicht sauber ist, richtig? 🤦‍♂️
Nein, das muss es nicht bedeuten. Zum einen zeigt der Task Manager nur die Windows Sicht an und nicht die interne Java Sicht. Und wenn es genug freien Speicher gibt aus Sicht der JVM, dann gibt es auch keinen Druck, dass der GC irgendwas frei gibt.

Und dann ist auch wichtig:
  • Der belegte Speicher muss ja nicht am BufferedReader liegen. Wir haben ja keinerlei Übersicht, was Du sonst noch so hast.
  • Der manuelle close Aufruf ist nicht optimal. try-with-resources sollte verwendet werden wenn es möglich ist.
 

izoards

Bekanntes Mitglied
Also ist das ein normales verhalten, wenn man das nicht begrenzt?
Apropos begrenzen, kann das mittels Launch4J mit dem Max. Heap. begrenzt werden?
Gibt es da Probleme, wenn man das begrenzt? Ich meine einfach, dass es unschön ist, wenn mein Programm hier soviel Arbeitsspeicher belegt.
1665605737423.png


  • Der belegte Speicher muss ja nicht am BufferedReader liegen. Wir haben ja keinerlei Übersicht, was Du sonst noch so hast.
Der Code ist zur Zeit noch nicht wirklich aufgeräumt / präsentierbar....
Aber dann denkst Du schon, dass der Code irgenwo noch unschönheiten hat, dass der Arbeitsspeicher kontinuierlich steigt?
  • Der manuelle close Aufruf ist nicht optimal. try-with-resources sollte verwendet werden wenn es möglich ist.
Danke für den Hinweis, dann befasse ich mich mal noch mit "try-with-resources"
 

KonradN

Super-Moderator
Mitarbeiter
Deine Fragen lassen sich pauschal nicht beantworten. Du weisst, was Dein Programm macht. Du kannst überschlagen, was da an Instanzen erzeugt wird und so. Damit kannst nur Du sagen, was da notwendig ist bzw. was Sinn macht.

Und wenn Du da nichts angibst, dann gelten die Default Werte, also beschränkt ist es so oder so. Die default Werte kannst Du mit einem Befehl wie
java -XX:+PrintFlagsFinal -version | findstr HeapSize
heraus finden. (Bei Linux / Mac statt findstr einfach grep verwenden).
 

izoards

Bekanntes Mitglied
Deine Fragen lassen sich pauschal nicht beantworten. Du weisst, was Dein Programm macht. Du kannst überschlagen, was da an Instanzen erzeugt wird und so. Damit kannst nur Du sagen, was da notwendig ist bzw. was Sinn macht.
Das Hauptprogramm startet einen Thread, welcher in einer Endlosschleife alle Sekunde dieselben Abfragen macht.
Im Hauptprogramm selbst, läuft noch ein Watchservice, welcher bei ankommen eines Files, den Thread stoppt. Das ansteigen des Arbeitsspeichers kann jedoch auf den Zusatzthread mit der Endlosschleife eingegrenzt werden bzw. auch dort, habe ich bereits viele Zeilen auskommentiert und kann den Grund für das ansteigen nicht finden... (Ist leider jedoch noch mit ziemlich verschachtelten if - statements programmiert)

IntelliJ meckert noch, dass ich in der Endlosschleife noch Thread.sleep() aufrufe...
Code:
Call to 'Thread.sleep()' in a loop, probably busy-waiting

Ansonsten sehe ich kein Grund für das Ansteigen des Arbeitsspeichers...



Code:
java -XX:+PrintFlagsFinal -version | findstr HeapSize

Das gibt bei mir für MaxHeapSize: 4'22'566'976kB, dann gibt das 4.22TB!?

Dann würde das Programm ohne Begrenzung soviel Speicherplatz einnehmen?
 

KonradN

Super-Moderator
Mitarbeiter
Kann es sein, dass du das kB da selbst hinzu gefügt hast? Das dürfte einfach nur die Zahl sein und dan wären das Bytes … und da dort ja immer mit 1024 gerechnet wird sollten das 4GB als Maximum sein.

Und davon dürftest du sehr weit weg sein, so dass der GC vor allem idle ist (wäre jetzt meine Vermutung).
 

izoards

Bekanntes Mitglied
Ja das kB habe ich nach kurzem googeln hinzugefügt, 4GB macht mehr sinn..

Ja, bin anfänglich bei 60MB das Programm soll aber non stopp laufen, darum mache ich mir die Gedanken.. denke werde es eifach auf 100MB begrenzen, macht das Sinn?
 

KonradN

Super-Moderator
Mitarbeiter
Ich würde Prozesse nicht zu sehr begrenzen. Aber du kannst mit so einem Limit testen, ob es weiter ansteigt oder ob der GC dem dann Einhalt gebietet.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A stack Java Basics - Anfänger-Themen 14
Proxy Stack erweitern mit neuem Array falls der alte voll ist!? Java Basics - Anfänger-Themen 5
V Ist Off-Heap-Speicher dasselbe wie Stack-Speicher? Java Basics - Anfänger-Themen 2
Csircc Rekursive Methode Stack Overflow Java Basics - Anfänger-Themen 10
B Zahlenfolge von Queue in Stack Java Basics - Anfänger-Themen 29
L Stack bilden, push und pop Java Basics - Anfänger-Themen 16
KogoroMori21 Stack und Heap Speicher Java Basics - Anfänger-Themen 1
G Stack und Queue Arbeitsblatt Java Basics - Anfänger-Themen 3
G Stack programmieren Java Basics - Anfänger-Themen 6
Z Datentypen Stack based calculator Java Basics - Anfänger-Themen 8
F speicherort stack oder heap Java Basics - Anfänger-Themen 1
S Rekursiven Stack Java Basics - Anfänger-Themen 6
Curtis_MC Collections Zufälliges Element aus Stack Java Basics - Anfänger-Themen 2
D Queue vs. Stack Java Basics - Anfänger-Themen 6
P Stack, Heap Java Basics - Anfänger-Themen 13
D Erste Schritte Stack im Rollenspiel Java Basics - Anfänger-Themen 76
J Stack mit Benutzereingabe Java Basics - Anfänger-Themen 17
J Liste,Queue,Stack sortieren Java Basics - Anfänger-Themen 2
C Stack und Queue in Aktion (Bitte Hilfe für die Klausur) Java Basics - Anfänger-Themen 7
S Sequenz von Zahlen bei einem Stack möglich oder nicht möglich? Java Basics - Anfänger-Themen 5
E Stack vs Queue - Gemeinsamkeiten / Unterschiede Java Basics - Anfänger-Themen 7
C Laufzeit von Stack Operation Java Basics - Anfänger-Themen 5
4 Stack over flow bei rekursiver Tiefensuche Java Basics - Anfänger-Themen 5
J Quicksort mit Stack Java Basics - Anfänger-Themen 4
A Anzahl der Elemente in einem Stack wiedergeben Java Basics - Anfänger-Themen 3
T Stack Overflow - Rekursive Fibonacci Java Basics - Anfänger-Themen 10
K Tiefen- und Breitensuche beim Baum durch Stack und Warteschlange Java Basics - Anfänger-Themen 1
L Liste mittels Stack implementieren Java Basics - Anfänger-Themen 0
A Stack programmieren -> Unklarheiten Java Basics - Anfänger-Themen 1
C Stack - listenbasierte Implementierung Java Basics - Anfänger-Themen 4
L Mit rekursiven Aufrufen einen Stack emulieren Java Basics - Anfänger-Themen 1
T Frage zu Java Stack Java Basics - Anfänger-Themen 5
D Stack-Objekt - LIFO - wait(); notify(); Java Basics - Anfänger-Themen 0
J Array von Objekten, wie schauts im Heap / Stack aus ? Java Basics - Anfänger-Themen 7
M Frage zu Stack und Heap Java Basics - Anfänger-Themen 1
Farbenfroh Suche Übungsaufgaben: BinaryTree, Stack Java Basics - Anfänger-Themen 0
D Aufgabe: Stack mit Iterator Java Basics - Anfänger-Themen 8
X Stack mit Oberklasse, wieso funktioniert es nicht? Java Basics - Anfänger-Themen 8
B Stack/Heap Frage Java Basics - Anfänger-Themen 36
K Probleme mit stack Java Basics - Anfänger-Themen 7
K Wofür wird heute noch die Stack Klasse in Java genutzt Java Basics - Anfänger-Themen 4
F Rekursion Tiefensuch-Problem - Stack Overflow Java Basics - Anfänger-Themen 9
P LinkedList - Stack ... grundlegende Frage Java Basics - Anfänger-Themen 5
B Stack in eine verkettete Liste pushen Java Basics - Anfänger-Themen 4
J OOP Warum braucht man den Stack Java Basics - Anfänger-Themen 3
B Queue mit Daten aus einem Stack füllen Java Basics - Anfänger-Themen 21
G Stack invertieren Java Basics - Anfänger-Themen 3
H Pseudo-Stack (char[] stackArray) mit Zeichen aus einer .txt-Datei befüllen Java Basics - Anfänger-Themen 5
S Stack Problem mit Objekt Java Basics - Anfänger-Themen 2
X String mit String von Objekt im Stack vergleichen? Java Basics - Anfänger-Themen 14
D Stack auslesen mit pop Java Basics - Anfänger-Themen 2
S Stack als verkettete liste/ toString methode Java Basics - Anfänger-Themen 3
S Exceptions bei push/pop in Stack Java Basics - Anfänger-Themen 8
S Eigene Stack Klasse Java Basics - Anfänger-Themen 26
S Stack: Klasseninvariante Java Basics - Anfänger-Themen 4
L OOP Wrapper Klassen - Stack-Aufgabe Java Basics - Anfänger-Themen 2
M Frage zu Stack Java Basics - Anfänger-Themen 3
D Problem mit Set, Stack und Random Java Basics - Anfänger-Themen 2
O Stack Implementierung als verkettete Liste Java Basics - Anfänger-Themen 8
T Probleme bei einen Stack der über drei Dateien funktionieren soll Java Basics - Anfänger-Themen 5
V java.util.Stack Java Basics - Anfänger-Themen 9
K Stack und immer gleiches Objekt Java Basics - Anfänger-Themen 11
kulturfenster Stack / Queue Implementationen Java Basics - Anfänger-Themen 11
S Stack einlesen. Java Basics - Anfänger-Themen 2
E Stack kann nicht implimentiert werden Java Basics - Anfänger-Themen 11
E Eigene Stack Klasse schreiben Java Basics - Anfänger-Themen 12
J Stack Java Basics - Anfänger-Themen 3
K min-int-Wert in'nem Stack Java Basics - Anfänger-Themen 8
L Stack UpnRechner Java Basics - Anfänger-Themen 4
B Stack mit Bildern füllen Java Basics - Anfänger-Themen 2
B Stack mit Strings in zufälliger Reihenfolge füllen Java Basics - Anfänger-Themen 4
J Stack, der Integer-Zahlen enthält Java Basics - Anfänger-Themen 3
K Array Stack Java Basics - Anfänger-Themen 6
O Stack-Klasse Java Basics - Anfänger-Themen 7
S Stack mit Arrays Java Basics - Anfänger-Themen 3
T generischer stack Java Basics - Anfänger-Themen 3
Z Keller/Stack Problem Java Basics - Anfänger-Themen 11
H Stack und Queue Java Basics - Anfänger-Themen 6
M Stack SetValTop Java Basics - Anfänger-Themen 6
G Die Klasse Stack selber schreiben. Java Basics - Anfänger-Themen 2
F Klammertest mit Stack implementieren Java Basics - Anfänger-Themen 5
X Stack Java Basics - Anfänger-Themen 14
J Morgen Java-Klausur. Stack, Heap, Method-Area Java Basics - Anfänger-Themen 2
H Unterschied zwischen Stack und Array Java Basics - Anfänger-Themen 3
F MergeSort iterativ mit Hilfe von Stack Java Basics - Anfänger-Themen 5
S stack Java Basics - Anfänger-Themen 3
S Stack invertieren Java Basics - Anfänger-Themen 14
S Stack-Operationen Java Basics - Anfänger-Themen 59
S Stack.pop() wie genau funktioniert das? Java Basics - Anfänger-Themen 3
A Stack, Frage zur Methode push Java Basics - Anfänger-Themen 4
C Anzahl der Elemente auf einem Stack Java Basics - Anfänger-Themen 4
D Stack chaos Java Basics - Anfänger-Themen 2
megachucky kleines problem mit nem STACK Java Basics - Anfänger-Themen 8
I Stack ist auf einmal empty Java Basics - Anfänger-Themen 3
R Beispiele für Stack & Visualisierung Java Basics - Anfänger-Themen 2
R Stack: Wieso funktioiert das? Java Basics - Anfänger-Themen 2
B eine kleine leichte aufgabe mit einem stack programmieren Java Basics - Anfänger-Themen 2
N Stack-Probleme Java Basics - Anfänger-Themen 2
K Stack Overflow Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben