Java 파일 흐름 종료 및 쓰레기 수거 메커니즘
4620 단어 java파일 흐름쓰레기 회수 메커니즘
import java.io.FileInputStream;
public class TTT {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
final String threadId = "thread_" + i;
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println(threadId + " started!");
try {
FileInputStream fis = new FileInputStream("/opt/test.log");
Thread.sleep(60 * 1000);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(threadId + " stopped!");
}
});
thread.start();
}
Thread.sleep(10 * 60 * 1000);
}
}
2. linux에서 이 클래스를 컴파일하고 실행한 다음 linux의 명령/usr/sbin/lsof-p
$ /usr/sbin/lsof -p `ps -ef | grep java | grep TTT | awk '{print $2}'` | grep "test.log"
java 21562 fkong 3r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 4r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 5r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 6r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 7r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 8r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 9r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 10r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 11r REG 253,0 0 35471424 /opt/test.log
java 21562 fkong 12r REG 253,0 0 35471424 /opt/test.log
10개의 루틴이 실행되었든 실행되었든 lsof 명령을 사용하여 본 결과와 마찬가지로 10개의 파일 흐름이 닫히지 않은 것을 볼 수 있습니다.3. 아래에서 나는 이 코드를 변경했다. 바로 라인이 실행된 후에 모든 라인을null로 설정하는 것이다. 다음과 같다.
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
public class TTT {
public static void main(String[] args) throws Exception {
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
final String threadId = "thread_" + i;
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println(threadId + " started!");
try {
FileInputStream fis = new FileInputStream("/opt/test.log");
Thread.sleep(60 * 1000);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(threadId + " stopped!");
}
});
thread.start();
threads.add(thread);
}
Thread.sleep(2 * 60 * 1000);
for (Thread thread : threads) {
thread = null;
}
System.out.println("Clean up threads!");
Thread.sleep(10 * 60 * 1000);
}
}
다시 10개의 스레드 운행 과정과 운행이 끝난 후에 lsof를 사용하여 보았는데, 결과는 여전히 비슷했고, 10개의 파일 흐름이 닫히지 않았습니다.나는 다시 약간의 변경을 했다. 모든 라인을 null로 설정한 후에 (또는 JVM을 재촉하는 것처럼) 몇 번의 gc 조작을 했다. 다음과 같다.
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
public class TTT {
public static void main(String[] args) throws Exception {
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
final String threadId = "thread_" + i;
Thread thread = new Thread(new Runnable() {
public void run() {
System.out.println(threadId + " started!");
try {
FileInputStream fis = new FileInputStream("/opt/test.log");
Thread.sleep(60 * 1000);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println(threadId + " stopped!");
}
});
thread.start();
threads.add(thread);
}
Thread.sleep(2 * 60 * 1000);
for (Thread thread : threads) {
thread = null;
}
System.out.println("Clean up threads!");
System.gc();
System.gc();
System.gc();
System.out.println("Finished GC!");
Thread.sleep(10 * 60 * 1000);
}
}
lsof를 다시 사용하면 실행 중에도 10개의 파일이 열려 있는 것을 볼 수 있습니다. 하지만 "Finished GC!"그 후에 본 결과 열 개의 파일 흐름이 모두 닫혔다.마지막으로, 나는 아예thread를null로 설정한 문장을 삭제했고, 실행 결과도 위에서 gc작업을 실행한 결과와 일치합니다.
결국 JVM에서 닫히지 않은 IO 파일 흐름을 열면 더 이상 사용되지 않는 상황에서 다음에 Full GC를 할 때 모두 회수하지만 JVM이 이런 일을 하게 하는 것은 아무래도 좋지 않다. 아니면 그 옛말, 자신의 일을 스스로 하는 것이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
38. Java의 Leetcode 솔루션텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.