Ressourcenleck durch (virtuellen/echten) Thread

Barista

Top Contributor
Bei meiner Beschäftigung mit meinem Generator ist mir eingefallen, dass ein Ressourcen-Leck entstehen könnte, wenn der Consumer-Thread keine Daten mehr aus der Queue liest und der Supplier-Thread darauf wartet, seine Daten loszuwerden.

Zwar wird die Referenz aus dem Consumer-Thread irgendwann vernichtet, aber der (virtuelle oder echte) Thread hat eine Referenz auf die Queue und ist selbst irgendwo noch referenziert, solange die run-Methode nicht beendet wurde.

Das könnte auch in einer Web-App passieren, wenn der Benutzer den Browser schließt ohne den aktuellen Geschäftsprozess zu beenden.

Vielleicht könnte man einen Timeout machen, um das Leck zu beseitigen?

Kennt jemand noch eine andere/bessere Lösung?
 

Oneixee5

Top Contributor
Ein Thread existiert mindestens so lange bis er mit seiner Arbeit fertig ist. Also auch wenn er wartet. Man kann ihn auch nicht von außen beenden und auch nicht neu starten. Um einen Thread zu beenden ruft man .interrupt() auf und der Thread/Runnable/Task/Future muss intern den Interruptet-State auswerten und seine Arbeit einstellen, bspw. eine Schleife verlassen. Falls es noch Referenzen gibt, werden die Ressourcen vom GC auch nicht entsorgt, wie bei anderen Objekten auch.

Am einfachsten kann man damit umgehen, wenn man die Threads nicht selbst verwaltet. Über ExecutorService kann man so etwas sehr gut steuern. Dabei gibt es auch die Möglichkeit von Timeouts.

Eine Web-Anwendung ist aber noch mal eine andere Kategorie. Im JEE/JakartaEE-Umfeld sollte man keine Threads selbst verwalten. Es gibt da entsprechende Mechanismen der Plattform. Eigene Threads könnten das Transaktions-, Speicher- und Classloading-Managment stören.

Bei Spring bietet sich @Async und CompletableFuture an.
 

KonradN

Super-Moderator
Mitarbeiter
Ich würde Dir Empfehlen, hier die Problematiken deutlich besser aufzuteilen. Du hast hier Themen massiv vermischt, die nicht zu vermischen sind alleine schon, weil diese nicht zu vermischen sind (Weil auf komplett unterschiedlichen Ebenen!). Nehmen wir das Beispiel der Webanwendung:

Du hast da erst einmal die Hi Level Ebene:
  • Der Client sendet einen Request
  • Der Server macht daraufhin etwas (ohne Details zu betrachten) und schickt dann die Antwort - Request erledigt.

Da gibt es bei dieser Sicht de genannte Problematik einfach nicht, dass der Server da irgendwas macht um dann zu warten ob da evtl. noch weitere Requests kommen. Klar, mit einer Stateful Connection / Session kann man sich da irgendwas bauen, aber das führt dann tatsächlich dazu, dass man dann in diverse Probleme hinein rennt wie z.B. eine direkte Limitierung der Anzahl der möglichen parallelen Clients und so.

Daher bedeutet das doch unter dem Strich, dass Du eine Art Paging hast. Es kommt der Request. Ja, das Ergebnis könnte von mir aus von 0 ... MAX_LONG gehen, aber pro Request kommen genau x Elemente (also z.B. 100 oder 1000). Wenn also der erste Request kommt, dann baust Du den "Generator" von 0...999 ... beim folgenden Request kommt dann 1000 ... 1999, ... Aber natürlich bist Du fertig, wenn Du das Ergebnis da hast.

Das ist ja auch, was Du jetzt schon hast: Du generierst den Generator (allerdings mit Ziel MAX_LONG) um dann nach 999 Elementen zu stoppen.

Klar, es kann jetzt Folgeprobleme geben. Die Erzeugung des Generators kann extrem teuer sein und der Client mag sehr viele Requests abschicken, die bedient werden müssten. Dann kann es Sinn machen, nicht für jeden Request einen neuen Generator zu erzeugen. Das ist aber dann doch keine wirkliche Thematik vom Generator. Der Generator generiert nur. Und das innerhalb gewisser Grenzen. Hier kommen dann einfach die für diese Probleme typischen Lösungen ins Spiel - die alle auf unterschiedlichen Ebenen ansetzen und unabhängig voneinander sind:
a) Caching Möglichkeiten. Dann hast Du halt ggf. bei einem Request doch einen etwas universelleren Generator gebaut. Dieser landet in einem Cache. Anfragen gehen also immer an den Cache um einen Generator zu bekommen. Und der Cache kann die Verwaltung aktiv übernehmen. Ein typisches Beispiel hier wäre z.B. das Connection Pooling.
b) Evtl. hast Du tatsächlich eine Art Session. Welcher Art das ist, ist offen. Wichtig ist dann, dass jeder CLient einen aktiven Gegenpart hat. Und dieser Gegenpart wird verwaltet. Bei der typischen Session wäre das dann tatsächlich der mögliche Timeout, der die Session dann nach gewisser Zeit beendet. Hier hat man aber meist einfach nur, dass Daten vorgehalten werden. Alleine schon, um skalierbar zu bleiben ... Aber das wäre ein (altes) Thema, zu dem man sehr viel findet inkl Dingen wie eine zentrale Verwaltung von Sessions. Eine aktuelle Variante könnte hier sein, dass man sowas über WebSocket anspricht. Dein Client baut also eine Verbindung auf und die kann dann etwas machen. Die Verbindung wird dann irgendwann geschlossen und das umfasst auch den Fall: Webanwendung wird geschlossen.

Oft hat man sowas aber auch komplett getrennt: Irgendwas wird generiert, weil es generiert werden muss. Das läuft dann unabhängig von Clients und so. Einfaches Beispiel: Jahres- oder Monatsabschluss. Das läuft dann im Hintergrund und es wird irgendwas an Daten generiert und gespeichert. Das mag zwar von einem Client angetriggert worden sein, aber das ist dann ein eigenständiger Ablauf. Clients können dann die Ergebnisse abrufen und betrachten.

Was für Ansätze möglich und denkbar sind, hängt von den genauen Anforderungen ab und was da genau gemacht wird. Aber das hat auf den Generator relativ wenig Einfluss. Der Generator mag da dann ggf. unterschiedliche Features benötigen, aber dies sind dann immer Low Level Features - halt auf Ebene des Generators.

Zwar wird die Referenz aus dem Consumer-Thread irgendwann vernichtet, aber der (virtuelle oder echte) Thread hat eine Referenz auf die Queue und ist selbst irgendwo noch referenziert, solange die run-Methode nicht beendet wurde.
Auf diesen konkreten Fall möchte ich noch eingehen: Das ist doch erst einmal kein wirkliches Problem aber es erfordert natürlich ein sauberes Programmieren. In Java wäre es das try-with-resources und AutoClosable. In C# wäre es IDisposable. Dein Consumer Thread ist verantwortlich für den Generator. Und wenn der Consumer Thread fertig ist, dann wird halt der Generator geschlossen. Und der Generator ist natürlich so zu schreiben, dass hier ein Schließen möglich ist. Also wenn Du hier mit eigenen (virtuellen) Threads arbeitest, dann hast diese zu wecken und der Thread muss sich dann auch beenden. (So Du hier per einzelnen Threads vorgehen willst. Denkbar sind auch andere Ansätze aber die kommen halt vor allem aus der Zeit vor virtuellen Threads.)

Also ja: Das sind durchaus typische Dinge und man muss hier tatsächlich sauber entwickeln. Und wenn man dann Java Mittel anschaut, dann kann der Generator sowas wie ein Stream sein - und wenn wir uns Stream<T> ansehen: dieser implementiert AutoClosable...
 

Barista

Top Contributor
In Java wäre es das try-with-resources und AutoClosable.
Das hilft nicht, wenn der virtuelle Thread über mehrere Requests leben soll.

Das ist doch erst einmal kein wirkliches Problem
Ich habe damit kein Problem, ist mir aber eingefallen. Ich hätte das Thema lieber unter der Kategorie Diskussion erstellen sollen.
Daher bedeutet das doch unter dem Strich, dass Du eine Art Paging hast. Es kommt der Request. Ja, das Ergebnis könnte von mir aus von 0 ... MAX_LONG gehen, aber pro Request kommen genau x Elemente (also z.B. 100 oder 1000). Wenn also der erste Request kommt, dann baust Du den "Generator" von 0...999 ... beim folgenden Request kommt dann 1000 ... 1999, ... Aber natürlich bist Du fertig, wenn Du das Ergebnis da hast.
Paging wäre ein Beispiel.

Der Generator wird nicht geschlossen, wenn der Client nicht alle Seiten abholt.
Also wenn Du hier mit eigenen (virtuellen) Threads arbeitest, dann hast diese zu wecken und der Thread muss sich dann auch beenden.
Ich habe zu wenig Ahnung davon, Die bisherigen Beispiele mit virtuellen Threads, die ich gesehen habe, haben mit eigenen Pools gearbeitet.
Java:
Thread.ofVirtual().start(runnable);

Keine Ahnung, wie man einen virtuellen Thread mit einem konkreten echten Thread aufweckt.

In den vielen Frameworks, die virtuelle Threads einsetzen, wird es wahrscheinlich eine Lösung geben.
 

KonradN

Super-Moderator
Mitarbeiter
Keine Ahnung, wie man einen virtuellen Thread mit einem konkreten echten Thread aufweckt.
Dann schau doch einfach einmal in die Dokumentation! Dann erkennst Du, dass Du bei start weiterhin eine Thread-Instanz zurück bekommst. Hier wird also nicht mehr unterschieden zwischen virtuellen Threads und eben den nicht virtuellen Threads.

Dazu brauchst Du auch keine zusätzlichen Frameworks und so.

Der Generator wird nicht geschlossen, wenn der Client nicht alle Seiten abholt.
Die bisherigen Beispiele mit virtuellen Threads, die ich gesehen habe, haben mit eigenen Pools gearbeitet.
Also hier ist die generelle Fragestellung doch: Wozu braucht der Generator einen eigenen Thread? Was willst / musst Du erreichen? Was sind die genauen Anforderungen?

Der generelle Ansatz wäre aus meiner Sicht, da einfach Schritt für Schritt heran zu gehen. Um dann immer mehr an Anforderungen hinzu zu nehmen und umzusetzen. Und dann nicht den Ansatz wählen: Andere Sprachen / Frameworks haben xyz - wie kann ich xyz in Java 1:1 umsetzen. Statt dessen solltest Du schauen: Was für Mittel gibt mir das Umfeld, welches Du nutzen willst, Dir an die Hand. Das sind dann z.B. die Mittel von Java. Aber wenn Du spezielle Frameworks / APIs nutzen willst wie Spring Boot, Jakarta EE oder ähnliches, dann geht es auch vor allem um diese. (Dazu dann ja auch der Post von @Oneixee5, der da auf diverse Punkte hingewiesen hat.

Der Sinn eines solchen Generators wäre das Überleben mehrerer Requests, das Erhalten des Status über mehrere Requests.
Diesbezüglich habe ich Dir ja auch einige Hinweise gegeben, was es diesbezüglich für Möglichkeiten / Ideen gibt.

Es ging nicht um das vermischen von Themen, sondern um das Zeigen von Möglichkeiten, unter denen solche Lecks entstehen können.
Ich sehe das etwas anders. Denn ich sehe da zum einen die Thematik, dass da Ressourcen nicht richtig verwaltet werden (Der Hinweis mit try-with-resources und AutoClosable) und zum Anderen, dass dann das Kein Thema mehr des Generators selbst ist (Der würde bei Close halt dafür sorgen, dass ein möglicher Thread beendet wurde - so dass eben die notwendige Implementierung sein sollte.) sondern eben die Nutzung des Generators. Diesbezüglich habe ich ja Hinweise gegeben Richtung Sessions, Caches/Pools, ...
Aber wie gesagt: Das sind zwei getrennte Themen bei der Implementierung: Das eine ist der Generator, den Du entwickelst und davon losgetrennt ist dann die Verwendung des Generators in irgendwelchen Umgebungen.

Es gibt eine Methode zum Parken.

Die Methode zum Unparken hat aber keinen Thread als Parameter, setzt eher Infos für den Pool oder so.

Die alten suspend- und resume-Methoden sind deprecated.
Thread.sleep() und Thread.interrupt() ist vermutlich, was Du Dir näher ansehen möchtest.
 

Barista

Top Contributor
Wozu braucht der Generator einen eigenen Thread? Was willst / musst Du erreichen? Was sind die genauen Anforderungen?
Das habe ich ganz am Anfang in dem anderen Gespräch beschrieben.
Aber wenn Du spezielle Frameworks / APIs nutzen willst wie Spring Boot, Jakarta EE oder ähnliches, dann geht es auch vor allem um diese. (Dazu dann ja auch der Post von @Oneixee5, der da auf diverse Punkte hingewiesen hat.
Will ich nicht nutzen, danke für unerwünschte Hinweise.

Mir wird das hier zu polemisch.
Aber besser als gar keine Reaktion.

Es gibt hier leider keinen passenden Gesprächspartner für mich zu diesem Thema in diesem Forum.
 

KonradN

Super-Moderator
Mitarbeiter
Das habe ich ganz am Anfang in dem anderen Gespräch beschrieben.
Nein, hast Du aus meiner Sicht nicht.

Mir wird das hier zu polemisch.
Was genau war bitte polemisch?

Es gibt hier leider keinen passenden Gesprächspartner für mich zu diesem Thema in diesem Forum.
Die Antworten hängen nun einmal auch immer mit davon ab, wie viel Mühe man sich gibt, bei seinen Anfragen....

Wenn ich vermuten müsste, dann würde ich behaupten, dass Du eingeschnappt bist, weil ich nicht Deiner Meinung war in dem anderen Thread bezüglich Klassen und Instanzen. Du suchst Unterstützung hier und lehnst jegliche sachliche Kommunikation geradezu ab. Und nein - hier im Forum sind keine Gedankenleser oder ähnliches. Sorry, wenn Du davon so massiv enttäuscht bist. Aber evtl. findest Du ja irgendwo ein Forum in dem nicht nur Muggle sind. (Ja, das war jetzt tatsächlich polemisch!)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
V Java-Codierungsherausforderung: Navigieren durch die Macken der Datumsmanipulation Allgemeine Java-Themen 2
H Dienst durch ssh forwarding absichern? Allgemeine Java-Themen 15
M Klasse durch Klassen Aufteilung verbessern, aber wo? Allgemeine Java-Themen 1
M Kein Scanner Fehler durch falsche EIngabe Allgemeine Java-Themen 4
P Karate API Test läuft nicht durch . initializationError Allgemeine Java-Themen 21
Y Wie bekomme ich durch getImage an das Image heran? Allgemeine Java-Themen 1
T Meine Frage lautet wie ich 2 CSV Dateien miteinander in Java verbinde und Spalten die zueinander gehören durch den gleichen Key zusammen ausgebe? Allgemeine Java-Themen 5
W Java Telegram Bot - Eingabe durch User Allgemeine Java-Themen 2
Drachenbauer Wie kann ich das Wort "concrete" in einem String durch ein anderes Wort ersetzen lassen? Allgemeine Java-Themen 5
I Buchstabe durch seinen Nachfolger ersetzen Allgemeine Java-Themen 29
M Jdeps-Error durch multi-release Allgemeine Java-Themen 6
J Reflection Aufruf: .class durch .dll ersetzen Allgemeine Java-Themen 4
mrbig2017 Threads wait wird nicht durch notify beendet! Allgemeine Java-Themen 3
C OpenCl Setup und durch JavaCode ansteuern Allgemeine Java-Themen 17
J Erste Schritte Datenspeicherung durch Java Allgemeine Java-Themen 6
M Hässliche Schrift auf Graphics durch deriveFont Allgemeine Java-Themen 0
R Variable durch mehrere Methoden ändern und nutzen Allgemeine Java-Themen 17
Aruetiise Interface Position durch JButton ermitteln Allgemeine Java-Themen 5
K Jar/DLL Abhängigkeiten durch User angeben lassen Allgemeine Java-Themen 6
4 Swing Durch klicken auf Button Labels einem Panel hinzufügen Allgemeine Java-Themen 4
R Rückgabe eines Arrays durch Funktion Allgemeine Java-Themen 9
T AWT AWT-EventQueue-0 Null_Pointer_Exception durch Variable Allgemeine Java-Themen 12
RalleYTN Problem bei Schleife die durch einen 2D raum iterieren soll Allgemeine Java-Themen 1
C Durch klicken von Button in GUI wird leeres Fenster geöffnet und nicht mein Spiel "Memory" Allgemeine Java-Themen 13
T Quadrieren einer Zahl nur durch Addition Allgemeine Java-Themen 5
L Vererbung If-Else ersetzen durch was? Allgemeine Java-Themen 20
K OOP OOP Gui Spiel + Vererbungen Probleme durch Nichtwissen!! Allgemeine Java-Themen 1
I CountDown wird durch JOptionPane unterbrochen Allgemeine Java-Themen 11
F JTable mit Zellen die sich durch andere Eingaben füllen Allgemeine Java-Themen 1
B Counting Sort (Sortieren durch Zählen) Allgemeine Java-Themen 13
Z Durch Bäume iterieren Allgemeine Java-Themen 3
M Unterbrechnung durch Echtzeitbefehle? Allgemeine Java-Themen 4
G Suchweg durch Binärbaum speichern Allgemeine Java-Themen 4
L Label- & Textfelderzeugung durch Button Allgemeine Java-Themen 1
S RandomAccessFile durch bytearrayinputstream ersetzen Allgemeine Java-Themen 4
H Java Leistungssteigerung durch Code Anpassung Allgemeine Java-Themen 5
H Optimierung durch Threads Allgemeine Java-Themen 31
S JTable: Model durch ein anderes ersetzen Allgemeine Java-Themen 2
P Variablen Auf durch for-Schleife generierte JComboBox zugreifen Allgemeine Java-Themen 3
T Code durch eigenes Frame pausieren (ähnlich JDialog) Allgemeine Java-Themen 4
F Live Ticker durch Screenshots Allgemeine Java-Themen 22
C Hex Zeichen ersetzen durch leer Zeichen Allgemeine Java-Themen 5
M Verschlüsselung von Text und Files durch RSA (Encoding Problem) Allgemeine Java-Themen 7
N Algorithmus durch Workflow Allgemeine Java-Themen 7
R Windows-Firewall lässt Java nicht durch Allgemeine Java-Themen 17
E Oracle kann durch 0 teilen !?! Allgemeine Java-Themen 7
E NetBeans Vector durch ArrayList ersetzen Allgemeine Java-Themen 4
J Java Datei durch Java Datei öffnen Allgemeine Java-Themen 16
M Arraynamen durch Variable festlegen lassen Allgemeine Java-Themen 5
R Implementierung eines Interface durch 2 verschiedene Klassen Allgemeine Java-Themen 6
S Bildaufbau durch Servlet -> Exception Allgemeine Java-Themen 11
F Slash durch Systembezogenen Fileseparator ersetzen Allgemeine Java-Themen 18
P JFormattedTextField für durch Semikolon getrennte Integer-Werte gesucht / Regulärer Ausdruck Allgemeine Java-Themen 3
M Eclipse drei slashs durch zwei ersetzen? Allgemeine Java-Themen 3
D Updaten von Klassen durch jar.exe zerstört diese. Update durch WinRAR gelingt! Allgemeine Java-Themen 2
A SWT Ausgabetext Shellscript durch Java Allgemeine Java-Themen 8
Ark Array durch Interface ersetzen Allgemeine Java-Themen 7
K Objekt einer konkreten Implementierung eines Interfaces durch übergebenen String Allgemeine Java-Themen 2
fastjack Hardwareinformationen durch Java auslesen Allgemeine Java-Themen 7
S durch Code steppen Allgemeine Java-Themen 7
E Durch System.in.read() blockierten Thread stoppen Allgemeine Java-Themen 10
M eigene Klasse durch Composition mit java.io.File erweitern Allgemeine Java-Themen 3
C Markierung durch Maus lesen Allgemeine Java-Themen 9
T Synchronisation von Listen bei Zugriffen durch mehrere Prozesse Allgemeine Java-Themen 15
N Scanner läuft nicht durch Allgemeine Java-Themen 2
F kamera auslösen durch Programm Allgemeine Java-Themen 17
M Maus durch JavaProgramm bewegen Allgemeine Java-Themen 2
Dissi Itext - Anordnung von Elementen durch PDF Writer Allgemeine Java-Themen 2
N Casten durch generic vermeiden ?? Allgemeine Java-Themen 10
H Performancegewinn durch Mehrfachobjeknutzung Allgemeine Java-Themen 3
N Fehler abfang läuft doppelt durch Allgemeine Java-Themen 2
H Performance Vorteil durch Wechsel der JVM? Allgemeine Java-Themen 6
G String.replaceall - mehrere Zeichen durch eines ersetzen Allgemeine Java-Themen 5
S Testen einer Anwendung durch klicken von Koordinaten Allgemeine Java-Themen 7
N int[] eindeutig durch eine Zahl repräsentieren Allgemeine Java-Themen 12
GilbertGrape Durch JDK debuggen Allgemeine Java-Themen 2
Q Objekte durch Reflection erzeugen Allgemeine Java-Themen 18
Chris81T Performance Problem durch mehrfaches Starten eines JAVA Prog Allgemeine Java-Themen 8
G Schleife durch Button beenden Allgemeine Java-Themen 6
royale Breitendurchlauf / Dijkstra durch Graph, vereinfacht Allgemeine Java-Themen 3
Hawkes Beschädigte Tarballs durch JavaTar Allgemeine Java-Themen 2
X Status Anzeige-durch Thread? Allgemeine Java-Themen 15
4 ich steige einfach nicht durch Allgemeine Java-Themen 5
P Thread Demonstrationr eist durch die Zeit Allgemeine Java-Themen 4
D erstellung einer seitenlangen xml durch ireport Allgemeine Java-Themen 3
R Jar-File vom Linux Desktop durch ancklicken starten? Allgemeine Java-Themen 5
M Java Programm durch Datei Öffnen Allgemeine Java-Themen 6
J IOException durch BufferedWriter.flush() ? Allgemeine Java-Themen 5
J Name eines Strings durch einen String festlegbar? Allgemeine Java-Themen 2
J Endlosschleife durch wechselseitigen Zugriff zweier Klassen? Allgemeine Java-Themen 2
J Zweidimensionales Array durch ZwischenArray ersetzen Allgemeine Java-Themen 3
T TreeMap durch Comparator mit Generics sortieren Allgemeine Java-Themen 9
J Chars in einem String durch "nichts" ersetzen Allgemeine Java-Themen 3
C Dateien auf Festplatte speichern durch "Durchsuchen-But Allgemeine Java-Themen 3
B VK_? << durch char rausbekommen Allgemeine Java-Themen 8
K Programm durch Tastendruck beenden Allgemeine Java-Themen 4
H Programmerweiterung durch Datei die Funktionen enthält Allgemeine Java-Themen 5
J Kommerzieller Einsatz von Java - Ich blick da nich durch. Allgemeine Java-Themen 14
T Mehrere Dateien byteweise durch stream schieben Allgemeine Java-Themen 9
D Thread durch Mouse-Event beenden Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben