1. 먼저 다음 코드를보십시오
import java.io.fileInputStream; public class ttt {public static void main (string [] args)은 예외 {for (int i = 0; i <10; i ++) {<10; i ++) {thread_ " + i; 스레드 스레드 = 새로운 스레드 () {public void run () {system.out.println (strood +"); "); = new fileInputStream ( "/opt/test.log"); thread.sleep (60 * 1000);} catch (예외) {ex.printstacktrace ();} system.out.println (strideid + "stop!"); ride.start ();} stread.sleep (10 * 60 * 1000);}}}}});2. Linux 에서이 클래스를 컴파일하고 실행 한 다음 Linux 명령/USR/SBIN/LSOF -P <PID>를 사용 하여이 프로그램에서 열린 파일 정보를보십시오.
$/usr/sbin/lsof -p`ps -ef | grep java | Grep ttt | awk '{print $ 2}'`| grep "test.log"Java 21562 Fkong 3R Reg 253,0 35471424 /opt/test.logjava 21562 Fkong 4R Reg 253,0 35471424 /opt/test.logjava 21562 Fkong 5R Reg 253,0 0 35471424 /opt/TEGAV. 21562 FKONG 6R Reg 253,0 35471424 /opt/test.logjava 21562 FKONG 7R Reg 253,0 35471424 /opt/test.logjava 21562 Fkong 8R Reg 253,0 35471424 /opt/test.logjava 21562 Fkong 21562 253,0 35471424 /opt/test.logjava 21562 Fkong 11R Reg 253,0 35471424 /opt/test.logjava 21562 Fkong 11r Reg 253,0 35471424 /opt/test.logjava 21562 FKONG 1253442442442442442442442442 /opt/test.log10 스레드가 실행 중이나 후에도 LSOF 명령을 사용하는 시청 결과는 동일합니다. 10 개의 파일 스트림이 닫히지 않았다는 것을 알 수 있습니다.
3. 아래 의이 코드를 변경했습니다.
import java.io.fileInputStream; import java.util.arraylist; import java.util.list; public class ttt {public static void main (string [] args)은 예외 {list <theld> 스레드 = new Arraylist <streld> (); int i = 0; i <10; i ++) {stlead (intrle); runnable () {public void run () {system.out.println (stride + "start!"); try {fileInputStream fis = new FileInputStream ( "/opt/test.log"); thread.sleep (60 * 1000);} catch (예외) {ex.printstacktrace ();} system.out.out.out.out.out.out. "정지!");}}); thread.start (); threads.add (stride);} stride.sleep (2 * 60 * 1000); for (스레드 스레드 : 스레드 = null;} system.out.println ( "스레드 정리!"); thread.sleep (10 * 60 * 1000);}}}}}}}. 다시 LSOF를 사용하여 10 스레드가 실행되는 동안 및 후에 볼 수 있으며 결과는 여전히 비슷하며 여전히 10 개의 파일 스트림이 닫히지 않습니다.
모든 스레드를 NULL로 설정 한 후 몇 가지 변경을 한 후 다음과 같이 몇 가지 GC 작업을 수행하도록 추가 (또는 JVM을 촉구합니다.
import java.io.fileInputStream; import java.util.arraylist; import java.util.list; public class ttt {public static void main (string [] args)은 예외 {list <theld> 스레드 = new Arraylist <streld> (); int i = 0; i <10; i ++) {stlead (intrle); runnable () {public void run () {system.out.println (stride + "start!"); try {fileInputStream fis = new FileInputStream ( "/opt/test.log"); thread.sleep (60 * 1000);} catch (예외) {ex.printstacktrace ();} system.out.out.out.out.out.out. "stop!");}}); thread.start (); threads.add (stride);} stride.sleep (2 * 60 * 1000); for (스레드 스레드 : 스레드 = null;} system.out.println ( "struch!"); System.gc (); system.gc (); System.out.out.out.out.out.out.out.out.out.gc (); gc! "); thread.sleep (10 * 60 * 1000);}}LSOF를 사용하여 다시보기 만하면 여전히 실행 중에 10 개의 파일 스트림이 열려 있지만 "완료된 GC!"이후에는 10 개의 파일 스트림이 닫혔습니다.
마지막으로 스레드를 NULL로 설정하는 진술을 간단히 삭제했으며 실행 결과는 위의 GC 작업을 수행 한 결과와 일치합니다.
결국, JVM에서 닫히고 닫히지 않은 IO 파일 스트림의 경우 다음 번에 전체 GC를 수행 할 때 더 이상 사용되지 않을 때 모두 재활용하지만 JVM이 이러한 일을하도록하는 것은 여전히 좋지 않습니다. 같은 오래된 말은 자신의 일을하는 것입니다.