결론적으로
파일 툴킷을 사용할 때 반환 값 유형에 각별히 주의해야 합니다. 두 인터페이스 Stream
및 DirectoryStream
인 경우 리소스를 해제하려면 즉시 close 메서드를 호출해야 합니다. 보다 우아한 try-with-resources 구조를 사용하는 것이 좋습니다.
릴리스 리소스에 가깝게 실행하지 않으면 Java 프로세스가 종료될 때까지 열린 파일 및 기타 리소스가 점유되며, 열린 리소스가 충분할 경우 Linux 시스템에서 구성한 프로세스 오픈 파일의 상한이 트리거되어 Java 프로세스가 종료될 수 있습니다. 프로세스가 비정상적으로 작동합니다. , 오류를 보고합니다.打开的文件过多
프로세스
먼저 파일 업로드 시 시스템 예외를 발견했습니다. 로그를 확인해 보니 열려 있는 파일이 너무 많은 것을 발견했습니다. lsof -p 47090 | wc -l
을 통해 Java 프로세스가 열려 있는 것을 발견했습니다. 4000개 이상의 파일. ulimit -a
또는 ulimit -n
을 통해 시스템 구성을 확인하십시오. 열린 파일의 상한은 1024입니다. lsof -p 47090
...
java 47090 root 472r DIR 253,2 47 15032447518 /home/bid/upload/53b9bbe6e29e7eadeffa7c03962108c5
java 47090 root 473r DIR 253,2 47 15032447518 /home/bid/upload/53b9bbe6e29e7eadeffa7c03962108c5
java 47090 root 474r DIR 253,2 50 16643000312 /home/bid/upload/799e6138b45ac922d9c34a218a47c3a8
java 47090 root 475r DIR 253,2 47 1077111019 /home/bid/upload/c942c119927d83a3d9bb4e13a46adc75
java 47090 root 477r DIR 253,2 53 7160 /home/bid/upload/66a37cd0d1f4c76c9aaafcfbb82203d9
java 47090 root 478r DIR 253,2 47 1077111019 /home/bid/upload/c942c119927d83a3d9bb4e13a46adc75
java 47090 root 481r DIR 253,2 53 1611530376 /home/bid/upload/41a9b0ca26a194bf204ccf83ee199c67
java 47090 root 482r DIR 253,2 50 5368709550 /home/bid/upload/8ec135c1594ef233337b2a041a558c20
java 47090 root 485r DIR 253,2 50 5368709550 /home/bid/upload/8ec135c1594ef233337b2a041a558c20
...
Java 프로세스를 다시 시작한 후 열린 파일 수는 약 350개이며 정상적으로 파일을 업로드할 수 있지만 업로드 파일 인터페이스가 호출됨에 따라 열린 파일 수가 계속 증가하고 해당 파일 디렉터리는 항상 열려 있어 업로드할 수 없습니다. , 스트림 등이 제 시간에 닫히지 않아 리소스가 해제되지 않은 것으로 의심됩니다.
코드를 확인하여 InputStream / OutputStream 등의 IO 스트림을 사용하지 않았으나 Files.list
메소드를 사용하고 그 반환 값 유형이 Stream<Path>
도 닫아야 합니다. try-with-resources 처리를 추가한 후 Java 프로세스를 다시 시작하면 열린 파일 수가 더 이상 증가하지 않고 약 350개로 유지되고 열린 파일 목록의 디렉터리 유형이 해제됩니다. 곧 문제 해결
파일 도구 클래스를 살펴보고 / <와 같은 여러 메소드가 Stream<Path>
또는 DirectoryStream<Path>
를 반환하는 것을 확인하세요. /span>, 모두 try-with-resources로 처리되어야 합니다. / / / find
lines
list
newDirectoryStream
walk