1. Schauen Sie sich zuerst den folgenden Code an
Importieren Sie Java.io.FileInputStream; public class ttt {public static void main (String [] args) löst eine Ausnahme aus {für (int i = 0; i <10; i ++) {Final String threadid = "Thread_" + i; Thread Thread = New Thread (New Runnable () {public void run () {) {system. = new FileInputStream ("/opt/test.log"); Thread.Sleep (60 * 1000);} catch (Ausnahme ex) {ex.printstacktrace ();} System.out.println (ThreadID + "Stop!");});2. Kompilieren und führen Sie diese Klasse unter Linux aus und verwenden Sie dann den Befehl Linux/usr/sbin/lsof -p <pid>, um die von diesem Programm eröffneten Dateiinformationen anzuzeigen.
$/usr/sbin/lsof -p `ps -f | Grep Java | grep ttt | awk '{print $ 2}' `| Grep "test.log" Java 21562 fkong 3r reg 253,0 0 35471424 /opt/Test.Logjava 21562 FKong 4R Reg 253,0 0 35471424 /opt/Test.Logjava 21562 FKong 5R reg 253,0 0 3547144 /opt/st.log. 21562 FKONG 6R REG 253,0 0 35471424 /opt/test 253,0 0 35471424 /opt/test.logjava 21562 fkong 11r reg 253,0 0 35471424 /opt/test /opt/test.logUnabhängig davon, ob es während oder nach 10 Threads ausgeführt wird, sind die Anzeigenergebnisse mit dem Befehl LSOF gleich. Sie können sehen, dass 10 Dateiströme nicht geschlossen sind.
3. Ich habe einige Änderungen an diesem Code unten vorgenommen, dh nachdem der Thread ausgeführt wurde, werden alle Threads wie folgt auf null gesetzt
Importieren Sie Java.io.FileInputStream; Import Java.util.ArrayList; Import Java.util.List; öffentliche Klasse TTT {public static void main (String [] args) löst Ausnahme aus {list <thread> threads = new SrayList <Thread> (); für (int i = 0; i <10; Runnable () {public void run () {System.out.println (ThreadID + "gestartet!"); Try {FileInputStream fis = new FileInputStream ("/opt/test.log"); Thread.sleep (60 * 1000); "Stoped!");}}); Thread.Start (); Threads.Add (Thread);} Thread.sleep (2 * 60 * 1000); Für (Thread: Threads) {thread = null;} System.out.println ("Threads!"); Verwenden Sie erneut LSOF, um während und nach den 10 Threads ausgeführt zu werden, und die Ergebnisse sind immer noch ähnlich, und es gibt immer noch 10 Dateiströme, die nicht geschlossen sind.
Ich habe einige Änderungen erneut vorgenommen, nachdem ich alle Threads in Null gesetzt habe, das JVM hinzufügen (oder fordert), wie folgt ein paar GC -Operationen durchzuführen: wie folgt:
Importieren Sie Java.io.FileInputStream; Import Java.util.ArrayList; Import Java.util.List; öffentliche Klasse TTT {public static void main (String [] args) löst Ausnahme aus {list <thread> threads = new SrayList <Thread> (); für (int i = 0; i <10; Runnable () {public void run () {System.out.println (ThreadID + "gestartet!"); Try {FileInputStream fis = new FileInputStream ("/opt/test.log"); Thread.sleep (60 * 1000); "Stop!");}}); Thread.Start (); Threads.add (Thread);} Thread.sleep (2 * 60 * 1000); Für (Thread: Threads) {Thread = null;} System.out.println ("Säuberung Threads!"); System.gc (); Gc! "); Thread.sleep (10 * 60 * 1000);}}Verwenden Sie LSOF, um erneut anzuzeigen, und Sie können immer noch sehen, dass 10 Dateiströme während des Ausführens geöffnet sind. Nach "Fersion GC!"
Schließlich habe ich einfach die Anweisungen gelöscht, die den Thread auf Null setzen, und die Ergebnisse des Laufs stimmen auch mit den Ergebnissen der obigen GC -Operationen überein.
Am Ende recyceln für diese IO -Dateiströme, die offen und nicht im JVM geschlossen sind, sie alle, wenn sie nicht mehr verwendet werden, wenn sie das nächste Mal volles GC machen, aber es ist immer noch nicht gut, die JVM diese Dinge tun zu lassen. Das gleiche alte Sprichwort ist, Ihre eigenen Dinge zu tun.