Java garbage collection thread
Ein thread ist Müll gesammelt, wenn der run()
- Methode in den thread beendet ist oder wenn die Funktion genannt wurde aus beendet?
Ich nicht ein Problem haben oder irgendetwas, aber ich möchte vermeiden, memory-leaks und so.
Für Menschen, die gerne code:
public void SomeClass {
public SomeClass() {
}
public void someMethod() {
Object data = veryBigObject;
while(true) {
MyThread thread = new MyThread(veryBigObject);
thread.run();
try {
Thread.sleep(1000);
} catch (InterruptedException e) { /* do nothing */ }
}
}
public static void main(String[] args) {
SomeClass myclass = SomeClass();
myclass.someMethod();
}
}
public class MyThread extends Thread {
private Object data;
public Thread(Object data) {
this.data = data;
}
public void run() {
//do stuff with data
}
}
In allen Sprachen, die ich kenne, Müll (wenn die Sprache, die hat jeder) entnommen wird, wenn eine Methode beendet. Ich gehe davon aus Java-als auch nicht. Das bedeutet, dass theoretisch die threads erstelle ich in someMethod()
werden nicht erfasst, bis someMethod()
endet. Wenn wir annehmen, dass die while-Schleife läuft für eine sehr lange Zeit, würde die Anwendung run out of memory und Abstürzen.
Meine Frage: ist das wahr? Wenn ja, was zu tun ist, es zu vermeiden?
- stackoverflow.com/a/2423293/798818
- In allen Sprachen, die ich kenne, Müll (wenn die Sprache, die hat jeder) entnommen wird, wenn eine Methode beendet. Zeigen Sie eine Sprache! Sie Fehler-garbage collection w/ automatic reference counting und C++ gleichermaßen Destruktor stack-Objekt zugeordnet. Java reserviert sich keine Objekte auf dem stack (durch design, aber es ist technisch möglich von EA [escape analysis] oder ED[nicht erkannt]) die Aussage ist falsch, im besten Fall (sehr falsch im schlimmsten Fall)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ersten, die in Java GC nicht deterministisch ist. Wenn das Objekt nicht mehr referenziert wird, ist es geeignet zu sein, werden in den nächsten GC-Lauf, aber es ist nicht zwingend. Auch fordern
System.gc()
ist nur ein Vorschlag, um das GC-system.Zweite, was zählt, sind Referenzen. In jeder Instanz der Schleife überschreiben Sie die Referenz auf das thread-Objekt. Wenn die threads fertig sind, gibt es keine Notwendigkeit zum verlassen der Methode haben Sie gesammelt (natürlich, während die threads ausgeführt werden, Sie werden nicht erfasst, selbst wenn Ihr code keine Verweise darauf). Die Frage verlassen der Methode, in der das Objekt erstellt wurde, ist nicht relevant.
Dem GC läuft, wenn es benötigt wird (z.B., wenn Sie versuchen, um Speicher zuzuweisen und den eden space voll ist)
Dies kann passieren, auf jede Zeile des Codes, wo Sie allocate memory (in jedem thread) Das bedeutet, selbst wenn Sie nicht, reservieren Sie Speicher in einem thread eine GC die immer noch auftreten können, weil Speicher zugewiesen wurde in einem anderen thread.
Können Sie auch auslösen, GC explizit oder mithilfe einer JMX-Tools wie visualvm.
Kurz: ein GC kann jederzeit auftreten.
Jede Instanz von MyThread wird markiert werden, um die Erfassung von GC nach dem start von den anderen loop-iteration. Wenn Sie ausführen möchten, MyThread, wie ein Faden, den Sie verwenden müssen, wird die start () - Methode!
In einem Fall, wenn Sie mit der start () - Methode MyThread wird markiert werden, um die Erfassung von GC nach dem start der anderen Schleife iteration und! das Ende der run () - Methode.
Aber es gibt keine Garantien darüber, Wann Sie abgeholt wird von der GC. Dies ist eine GC-spezifische Sache.
Ist es selbstverständlich, dass es auf dem thread aufgerufen nach, als es den job zu beenden und nicht mehr die Daten, aber nicht Wann, weil der garbage collector automatisch aufgerufen, indem Sie die virtuelle Maschine periodisch oder bei einigen Veranstaltungen auftreten.
Also aus, wenn der thread beendet wurde und die Daten werden nicht verwendete können Sie nicht wissen, ob der dat wurden automatisch gesammelt werden oder nicht.
Können Sie nennen es auch explizit mit:
System.gc()
.Wenn der thread beendet waren, und seine Spitzen, die Daten nicht mehr verwendet werden, nachdem der explizite Aufruf ist es selbstverständlich, dass Sie erhoben wurden.
In dem code, den Sie oben gepostet habe, kein Thread tatsächlich parallel ausgeführt. Zum laichen einen neuen thread, müssen Sie genannt haben, die
.start()
Methode ruft intern die.run()
- Methode für den Thread. Jetzt läuft alles der Reihe nach. Also dein thread.run() beenden Ihre Ausführung, Ihre aktuellen thread schlafen, und Ihrewhile
wird weiterhin seine Schleife und tun es immer und immer wieder.Den GC treffen kann an jeder beliebigen Stelle und, wie andere bereits gesagt haben, läuft threads (threads gestartet wurden, die mit
start()
) werden nur GCed, wenn Sie abgeschlossen haben Ihre Ausführung.