Wer kann mir das hier erklären? Programm frisst RAM!

xip

Bekanntes Mitglied
Hallo,

mein Programm frisst immer und immer mehr Speicher!

Java:
public class start {

	public static void main(String[] args) 
	{
		new start();
	}
	
	start()
	{
			for(int i = 0; i < 20 ; i++)
			{
				Thread obj_thread = new Thread(){
					public void run()
					{
						while(true)
						{
							String str_wert = this.getName(); // 
						}
					}
				};
				obj_thread.start();
			}
	}
}

doch das nun wirklich komische daran ist wenn ich das this.getName() welches einen normalen String zurückgibt gegen "hallo" oder sonst einen String austausche bleibt das Programm wie erwartet klein!! Habt ihr eine idee??


Java:
public class start {

	public static void main(String[] args) 
	{
		new start();
	}
	
	start()
	{
			for(int i = 0; i < 20 ; i++)
			{
				Thread obj_thread = new Thread(){
					public void run()
					{
						while(true)
						{
							String str_wert = "was soll das den???";
						}
					}
				};
				obj_thread.start();
			}
	}
}
 

eRaaaa

Top Contributor
getName() => return String.valueOf(name); => return new String(data);

es wird also jedes Mal ein neuer String erstellt.

Das andere ist eine "Konstante", die wird also im String-Pool abgelegt werden, d.h. du hast so immer nur diesen einen String !
 

Ebenius

Top Contributor
[c]Thread.getName()[/c] erzeugt je Aufruf eine neue String-Instanz. Das Programm wird Speicher benutzen wie es ihn zur Verfügung bekommt. Irgendwann wird der Garbage-Collector die unbenutzten String-Instanzen wieder auflösen. Wann das passiert, weiß die JVM allein.

Probier mal so:
Java:
public class Start {
 
    public static void main(String[] args) 
    {
        new Start();
    }
    
    Start()
    {
            for(int i = 0; i < 20 ; i++)
            {
                Thread objThread = new Thread(){
                    public void run()
                    {
                        for(int i = 0; ; i++)
                        {
                            String strWert = this.getName(); //
                            if ((i % 1000) == 0) {
                              System.gc();
                            }
                        }
                    }
                };
                objThread.start();
            }
    }
}

Ebenius

PS: KlassenNamen und variablenNamen angepasst.
 

xip

Bekanntes Mitglied
achso!!!

Habt vielen Dank.

Danke für die Trick mit dem System.gc(). Das kannte ich noch gar nicht!

Gruß
 

FArt

Top Contributor
Ein explizites antriggern des GC ist in der Regel sinnfrei. Die VM weiß am Besten, wann sie Speicher wie freigeben sollte. Diese Algorithmen sind bedingt konfigurierbar, was auch der Ansatzpunkt für Anpassungen an die eigenen Bedürfnisse sein sollte. Ein Eingriff über den Code wird in der Regel zu einer schlechtern Performance führen, schwer oder gar nicht mehr zu optimieren.
 

Ebenius

Top Contributor
Da stimme ich zu. Ich habe den Aufruf unten nur zum Test eingebaut, damit man sehen kann, dass kein wirkliches Leck besteht.

Ebenius
 

aumaster

Mitglied
Hi xip,

Dein Quelltext ist ein gutes Beispiel dafür, wie man mit Threads nicht umgehen sollte... :noe:

Leider kann ich nicht mal erahnen, was Dein Programm überhaupt machen soll.
Soll es einfach die Namen der gestarteten Threads ausgeben? Na ja, egal.

Zwei Grundsätze:

1.) Man deklariert keine Variablen IN einer FOR-Schleife sondern DAVOR.
Mit jedem Durchlauf der Schleife wird sonst eine neue Instanz der Variablen erzeugt. Das kostet Arbeitsspeicher!

2.) In der run() Methode niemals while(true) verwenden da:
a.) Die Prozessorlast dann bei 100% liegt
b.) Sich der Thread nicht korrekt beenden lässt


Hier ein Beispiel wie man mit Threads richtig umgeht (und natürlich frisst das kein RAM...):

Java:
   public static void main(String[] args) {
        ThreadGroup threadGroup = new ThreadGroup("tg");
        Thread objThread;
        for (int i = 0; i < 20; ++i) {
            objThread = new Thread(threadGroup, "thread_" + i) {
                public void run() {
                    while (!isInterrupted()) { //nicht while(true)...
                        try {
                            //Macht irgendwas...
                            System.out.println("Hier Thread \"" + getName() + "\". Ich mache irgendwas...");
                            sleep(1000);
                        } catch (InterruptedException e) {
                            System.out.println("Thread \"" + getName() + "\" wird beendet!");
                            return; //Und raus aus der run() Methode...
                        }
                    }
                }
            };
            objThread.start();
        }

        //Nun machen wir mal nix und lassen die 20 Threads 10 Sekunden laufen...
        try {
            Thread.sleep(10000);
        } catch (InterruptedException ignore) {}

        //Nun durchlaufen wir die ThreadGroup und lassen uns den Namen der Threads ausgeben
        //und beenden sie anschliessend...
        Thread[] objThreads = new Thread[threadGroup.activeCount()];
        threadGroup.enumerate(objThreads);
        for (Thread thread : objThreads) {
            System.out.println("Threadname: " + thread.getName());
            //So beendet/unterbricht man einen Thread korrekt
            thread.interrupt();
        }
  }

Ich hoffe das hilft...

Gruß, aumaster

P.S.: Ein Aufruf von System.gc() oder Runtime.getRuntime().gc() sollte man besser lassen.
Das hat meist die gegenteilige Wirkung und frisst oft noch mehr RAM anstatt was freizugegeben...
 
Zuletzt bearbeitet:

Ebenius

Top Contributor
Dein Quelltext ist ein gutes Beispiel dafür, wie man mit Threads nicht umgehen sollte... :noe:
Der Quelltext ist ein Testprogramm. Natürlich ergibt es keinen weiteren Sinn. :bahnhof:

1.) Man deklariert keine Variablen IN einer FOR-Schleife sondern DAVOR.
Mit jedem Durchlauf der Schleife wird sonst eine neue Instanz der Variablen erzeugt. Das kostet Arbeitsspeicher!
Das ist Unsinn. Aus zwei Gründen:
  1. Man deklariert Variablen so knapp wie möglich. Wenn eine Variable außerhalb eines Blocks nicht benötigt wird, dann deklariert man sie auch nicht außerhalb.
  2. Ob die Variable außerhalb oder innerhalb der Schleife deklariert ist oder nicht hat mit der Speicherverwaltung genau nix zu tun. Die Instanzen werden aufgebaut, egal wo die Variable deklariert ist. Selbst wenn Du statt [c]String str_wert = this.getName(); //[/c] nur [c]this.getName(); //[/c] schreibst wirst Du das selbe Problem erfahren.

2.) In der run() Methode niemals while(true) verwenden da:
a.) Die Prozessorlast dann bei 100% liegt
b.) Sich der Thread nicht korrekt beenden lässt
Das ist ebenfalls Unsinn. Ein typischer, über Netzwerk erreichbarer Server macht genau das; er nimmt in einer [c]while(true)[/c]-Schleife Anfragen entgegen und arbeitet sie ab. Abgebrochen werden kann der Thread dann noch immer; entweder innerhalb der Schleife mit break oder per [c]interrupt()[/c] und zugehöriger InterruptedException. Ganz abgesehen davon, dass der Test oben ja absichtlich Last erzeugen soll!

Hier ein Beispiel wie man mit Threads richtig umgeht (und natürlich frisst das kein RAM...):[…]
Man leitet die Thread-Klasse nicht ab, nur um sie zu benutzen. Statt dessen übergibt man dem Thread ein Runnable das man implementiert. Die API-Doc des Runnable-Interfaces sagt dazu:
In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.

Ebenius
 

FArt

Top Contributor
Dieses mal stimme ich voll zu... oder fast voll.

Das ist ebenfalls Unsinn. Ein typischer, über Netzwerk erreichbarer Server macht genau das; er nimmt in einer while(true) -Schleife Anfragen entgegen und arbeitet sie ab. Abgebrochen werden kann der Thread dann noch immer; entweder innerhalb der Schleife mit break oder per interrupt() und zugehöriger InterruptedException. Ganz abgesehen davon, dass der Test oben ja absichtlich Last erzeugen soll!

while(true) ist zwar gängige Praxis, aber nicht die beste Lösung. Eine gute Lösung wäre, auf das Interrupted-Flag des Threads zu prüfen, denn eine InterruptedException wird ja nur empfangen, wenn der Thread gerade blockiert. Das wäre auch die beste Lösung einen Thread von außen zu beenden: ihn unterbrechen.
 

aumaster

Mitglied
Ah, ich sehe schon - keine Lösung gepostet, aber den Lösungsversuch
von anderen bewusst nicht verstehen wollen und dann verreissen... :toll:
 

Ebenius

Top Contributor
Ja genau. Das machen wir hier immer so. ;-)

Im Ernst: Meiner Meinung nach sollten Sätze nicht lauten "Niemals dies und das machen" wenn sie dann nicht unumstößlich sind. Dem Themeneröffner ging es im Übrigen eher daraum zu verstehen, wieso ein derartiges Programm -- auch wenn es effektiv keine Daten sammeln sollte -- trotzdem augenscheinlich immer mehr Speicher verbraucht. Und das hatte er beantwortet bekommen. Oder nicht?

Ebenius
 

FArt

Top Contributor
Ah, ich sehe schon - keine Lösung gepostet, aber den Lösungsversuch
von anderen bewusst nicht verstehen wollen und dann verreissen... :toll:

Heul doch! ;(

Es geht darum, dass der Threadstarter und alle, die diesen Thread in Zukunft lesen keine Fehlinformationen als Wahrheit annehmen, deshalb die Korrekturen.
Ich poste selten Code, aber ich gebe Lösungen bzw. Lösungsansätze. Erwartet jemand Code, antworte ich in der Regel nicht.
Ich finde es gut, dass hier jeder auch mal suboptimale Lösungen bzw. Beiträge postet.Nobody is perfect. Das ist ein Diskussionsforum und die Postings dienen zur Diskussion, damit jeder lernen kann, wie man es am Besten machen sollte, auch jemand, der vermeintlich eine Lösung gepostet hat. Das mit den Diskussionen verstehen viele nur nicht. Sie gehen davon aus, dass es hier kostenlosen, persönlichen Support bekommt... eine Fehleinschätzung!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
jhCDtGVjcZGcfzug Klassen Was genau passiert hier? Kann mir das jemand bitte Zeile für Zeile erklären? Allgemeine Java-Themen 1
Zrebna SonarLint: Warum kein Null-Referencing-CodeSmell-Hint hier? Allgemeine Java-Themen 23
Calli11 Was muss ich hier in die Main schreiben, damit das Programm ausgeführt wird? Allgemeine Java-Themen 4
C Was passt hier nicht bei der Calendar-Class Allgemeine Java-Themen 2
berserkerdq2 Kann keine Labels erstellen, was ist hier syntaktisch falsch Allgemeine Java-Themen 5
N Ist Selenium hier das richtige Werkzeug? Allgemeine Java-Themen 1
Zrebna Wieviele Testfälle muss man hier schreiben? (Software Engineering) Allgemeine Java-Themen 13
A Ist ein enum hier richtig? Enum toString() Methode. Allgemeine Java-Themen 1
Drachenbauer warum bekomme ich hier eine NullPointerException Allgemeine Java-Themen 6
X Wie mache ich hier eine Rekursion rein ? Allgemeine Java-Themen 7
S Eigenschaften (hier Verknüpfung) eines Files lesen Allgemeine Java-Themen 2
J Einrückungstool mit Farblicher hervorhebung wie hier? Allgemeine Java-Themen 3
V VisualVM Was erkennt ihr hier? Allgemeine Java-Themen 9
E Queue: Wie kann hier ein null-Pointer Exception auftreten?! Allgemeine Java-Themen 11
R Was ist hier falsch? Abfragen Allgemeine Java-Themen 3
S Singleton hier sinnvol? Allgemeine Java-Themen 20
E Wieso returnt das hier 1? Allgemeine Java-Themen 3
W Wieso funktioniert dieser Code hier? Allgemeine Java-Themen 6
G Warum kommt hier NullPointerException? Allgemeine Java-Themen 3
F Threading oder kein Threading - das ist hier die Frage. Allgemeine Java-Themen 23
D Timer oder Thread, das ist hier die Frage Allgemeine Java-Themen 3
egrath Anonyme Methode - warum hier kein Compilerfehler Allgemeine Java-Themen 2
F Gutes Threads Tutorial hier aber trotzdem eine Frage Allgemeine Java-Themen 7
M Spring oder nicht, das ist hier die Frage Allgemeine Java-Themen 3
S Was ist hier falsch? Allgemeine Java-Themen 16
G wer muss hier wen aufrufen? Allgemeine Java-Themen 7
M Kann man hier noch was rausholen? Allgemeine Java-Themen 16
A Was passiert hier? Allgemeine Java-Themen 13
I Ist JNI hier richtig? Allgemeine Java-Themen 8
B Gibts sogar hier Allgemeine Java-Themen 3
S Interpreter-Fehler Kann mir das mal einer erklären? Allgemeine Java-Themen 12
berserkerdq2 Kann jemand vereinfacht erklären was Maven ist? Allgemeine Java-Themen 8
M Praktische Möglichkeit um Studierenden Java zu erklären Allgemeine Java-Themen 33
J Programme erklären Allgemeine Java-Themen 1
U Set erklären dass objekte gleich sind Allgemeine Java-Themen 12
L HttpPost LookUp erklären Allgemeine Java-Themen 2
P JAVA Code in Dokumentation erklären Allgemeine Java-Themen 2
B Kann mir jmd folgendes erklären? Allgemeine Java-Themen 7
J Alghorimus erklären Allgemeine Java-Themen 14
N RegEx, kann mir das wer erklären? Allgemeine Java-Themen 6
F Wie Fachthemen richtig erklären? Allgemeine Java-Themen 6
Jose05 Umgang mit Exceptions in einen Programm Allgemeine Java-Themen 2
E Output Fehler (Java-Programm Kuchen) Allgemeine Java-Themen 11
S Java Programm lässt sich vom USB-Stick starten, aber nicht von HDD Allgemeine Java-Themen 16
R Programm führt Methoden gleichzeitig aus Allgemeine Java-Themen 2
T Der Aufruf von CMD-Programm Allgemeine Java-Themen 30
A Java Programm erstellen hilfe Allgemeine Java-Themen 10
Mike80 Processing Programm fiert ohne Arduino ein Allgemeine Java-Themen 2
B Mysteriöse Ergebnisse beim Baccarat Programm? Allgemeine Java-Themen 13
districon Programm zum Durchsuchen von (Ebay-)Artikeln Allgemeine Java-Themen 1
T Addons im eigenen Programm Allgemeine Java-Themen 1
S .exe Datei/Programm auslesen? Allgemeine Java-Themen 2
S Formel für Sonnenwinkel in ein Programm überführen Allgemeine Java-Themen 11
Alex_99 Programm stürzt beim Aufruf der Funktion ab? Text ausgeben Allgemeine Java-Themen 45
B Java Programm auf virutellem Desktop laufen lassen? Allgemeine Java-Themen 1
L Java überprüfen lassen, ob sich ein gegebener Pfad / das Programm an sich auf einer CD oder Festplatte befindet Allgemeine Java-Themen 14
Tiago1234 Warum hängt sich mein Programm auf? Allgemeine Java-Themen 22
D Programm designen Allgemeine Java-Themen 1
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
J c Programm läuft nicht in compilierter Version des Java Projektes Allgemeine Java-Themen 7
O 2D-Grafik BioFarben-Programm soll auf Vollbild schalten Allgemeine Java-Themen 1
S Nachrichten Filter Programm Allgemeine Java-Themen 14
S Programm schreiben, das mir aufgrund von Schlagwörtern, die ich im Internet suche, relevante Themen sofort anzeigt. Allgemeine Java-Themen 1
T Hilfe bei Programm. IDE: Eclipse mit EV3-Plugin, lejos Allgemeine Java-Themen 8
Lukas2904 Swing Anzeigen lassen das das Programm geschlossen wurde Allgemeine Java-Themen 3
TechnikTVcode Mail Programm Allgemeine Java-Themen 2
S Programm entwickeln, welches ein Dreieckspuzzle lösen kann Allgemeine Java-Themen 5
R Lesen von Interfaces (Programm Vervollständigen) Allgemeine Java-Themen 10
Dann07 Java-Programm findet DLLs nicht! Allgemeine Java-Themen 20
OSchriever Linux-Programm öffnen Allgemeine Java-Themen 6
P USER Management in SQL übergreifend auf JAVA Programm Allgemeine Java-Themen 41
L Eclipse Konsole im exportierten Programm Allgemeine Java-Themen 2
OSchriever Programm über Linux-Kommandozeile ausführen Allgemeine Java-Themen 20
D Verkauf von einem Programm welches ich in Java geschrieben habe Allgemeine Java-Themen 4
M Programm erkennt String aus .txt Datei nicht Allgemeine Java-Themen 3
P Erstelltes Programm ist doppelt so groß Allgemeine Java-Themen 11
N Programm nach Abschluss neustarten lassen Allgemeine Java-Themen 6
S Einfaches Programm programmieren Allgemeine Java-Themen 5
M kleines KI Programm Idee Allgemeine Java-Themen 7
D Boolean von ein anderem Java Programm während der Laufzeit ändern Allgemeine Java-Themen 23
L Excel Datei löscht sich selbst im Programm - Java Allgemeine Java-Themen 3
I File ausführen und mein Programm bearbeiten lassen Allgemeine Java-Themen 11
ralfb1105 Starten Java App(s) (.jar) aus einem Java Programm Allgemeine Java-Themen 18
temi Java Programm aus einer DB laden und starten Allgemeine Java-Themen 2
N Programm startet nicht, nur per cmd Allgemeine Java-Themen 5
J Programm zum Suchen eines Wortes im Dateisystem Allgemeine Java-Themen 4
E Java Programm mit Clients erweitern - Möglichkeiten? Allgemeine Java-Themen 2
Joker4632 Methoden Befehl an bereits extern geöffnete Programm-spezifische Konsole senden Allgemeine Java-Themen 1
M Dieses Programm schneller machen? Allgemeine Java-Themen 2
R Programm zur Rekursion Allgemeine Java-Themen 5
N Quicksort Programm hängt sich auf Allgemeine Java-Themen 6
S Compiler-Fehler Programm verhält sich in Eclipse anders Allgemeine Java-Themen 1
B Input/Output Programm zum Auslesen/Beschreiben von Textdateien, wie Geschwindigkeit erhöhen? Allgemeine Java-Themen 18
dereki2000 Programm veröffentlichen Allgemeine Java-Themen 14
mrbig2017 Threads Chat Programm mit Threads? Allgemeine Java-Themen 2
M Suche aktuelle Apache Poi Bibliothek zum Einbinden in mein Programm Allgemeine Java-Themen 2
J Java "Bank Programm" Brauche eure Hilfe Allgemeine Java-Themen 3
S Java Programm (Spiel mit den Boxen) Allgemeine Java-Themen 1
kodela Programm hängt in der Ereigniswarteschlange Allgemeine Java-Themen 13
A Java Programm verbessern/vereinfachen Allgemeine Java-Themen 20

Ähnliche Java Themen


Oben