Ich bin ein wenig Anfänger, wenn es um JAVA-Anwendungen geht, aber ich war an der Entwicklung einer ziemlich komplexen JAVA (8) -App beteiligt, die Multithreading erfordert. Ich selbst und ein anderer Entwickler sind immer wieder auf ein Problem gestoßen, bei dem die App nach einiger Zeit nicht mehr genügend Arbeitsspeicher hat.JAVA Multi-Threading, Speicherleck, Garbage Collector
Zuerst gaben wir der Anwendung 64 GB Arbeitsspeicher, aber nach ein paar Stunden hatte es nicht mehr genügend Arbeitsspeicher, Absturz und Neustart. Nur um es wieder und wieder zu machen. Kontext; Die Anwendung nimmt Nachrichten von einem Nachrichtensystem (ActiveMQ) und aus dem Meta der Nachricht muss eine XML-Datei erstellen, indem verschiedene Datenquellen nach Werten aufgerufen werden. Es könnte buchstäblich Millionen von Nachrichten geben, die verarbeitet werden müssen, also haben wir ein Multi-Threading-System entwickelt, jeder Thread behandelt eine Nachricht - und gab der Anwendung 40 Threads.
Da jedoch der Nachrichtenspeicher weiterhin belegt ist, steigt der Gesamtspeicherverbrauch im Laufe der Zeit an. Ich habe das Gefühl, dass der Müllsammler von uns nicht richtig genutzt wird?
Also im Moment haben wir einen Elternteil thread:
(new Thread(new ReportMessageConsumer(config, ""))).start();
Dann im ReportMessageConsumer wir X Anzahl der Threads eingerichtet haben, so würde dies 40 in unserem aktuellen Setup sein. Das wäre also alles unter dieser einen Gruppe. Sobald der XML-Code erstellt wurde und die Threads erledigt sind, wie können wir den Thread effektiv beenden und den Garbage Collector erzwingen, um diesen Speicher freizugeben, sodass wir dann einen neuen sauberen Thread erstellen können, um eine andere Nachricht aufzunehmen?
Ein Thread stirbt kurz nach seiner 'run()' Verfahren entweder Rückkehr oder eine Ausnahme ausgelöst. Wenn Ihr Code keinen Verweis auf das 'Thread'-Objekt beibehalten hat (und in Ihrem Beispiel wird eindeutig keins beibehalten), sollten das' Thread'-Objekt und alle Objekte, auf die der Thread-Stack verweist, sofort zum Wiederherstellen freigegeben werden durch den GC. –
Verwenden Sie keine Threads direkt, wenn Sie eine beenden und eine andere starten möchten, um "eine andere Nachricht" zu verarbeiten: Verwenden Sie Executoren. –
Was ist der genaue OutOfMemoryError, den Sie sehen? Ist es heap, stack, gc overhead, kann native Threads nicht erstellt werden? –