2010-02-16 3 views
57

열린 JVM :열려있는 파일이 너무 많습니다 : 얼마나 많은 사람들이 무엇인지, 개방, 얼마나 많은 수 나는 자바에서이 예외 얻고있다

java.io.FileNotFoundException: (Too many open files) 

나는이를 제거 할 수있는 방법을 찾고 있어요를 문제.

이 오류는 분명히 JVM이 너무 많은 핸들을 할당했으며 기본 OS가 더 이상 사용하지 못하게합니다. 어딘가에 부적절하게 닫힌 연결/스트림이있는 누출이 있습니다.

이 프로세스는 논스톱으로 실행되며 결국 예외가 throw됩니다. 12-14 일의 가동 후 반복적으로 발생합니다.

어떻게 싸우나요? JVM에서 할당 된 핸들 목록을 얻는 방법이 있습니까? 나는 그들을 인쇄하여 그것이 어떻게 성장하는지 볼 수 있기를 바랍니다. 프로덕션 시스템이고 개발시 재현하기가 어려우므로 프로파일 러를 사용할 수 없습니다. 어떠한 제안?

-Xmx에 지정된 총 용량의 1 %에 도달하면 사용 가능한 힙 크기를 모니터링하고 "경보"를 발생시킵니다. 또한 스레드 수가 500을 초과하면 확실히 무언가가 손에 닿지 않게됩니다. 자, 거기에 내 JVM이 너무 많은 핸들 OS에서 할당하고 그들을 돌려주지 않는 것을 알 수있는 방법입니다. 소켓, 열어 놓은 파일 등등. 내가 알았다면, 언제 어디서 볼지를 알고 있었을 것이다.

+1

당신이 더 많은 것을 제공 할 수 JVM 및 OS에 대한 정보? 또한 개발 환경에서이 문제를 재현하는 데 더 많은 노력을 기울이는 것이 좋습니다. 번거 로울 수 있지만 그런 문제가 생기면 프로덕션 시스템에서 "관찰 및보고"하는 데 오랜 시간이 걸릴 것입니다. – Timothy

+1

가상화를 실행하는 Linux에서 반복적으로 발생하며 2 주 동안로드가 많이 걸린 테스트를 실행하여이 문제를 재현 할 수있는 옵션이 없습니다. 나는 이것이 창문 상자에서 일어나는 것을 보지 못했다. 당신이 옳아 요, dev에 잡는 것이 가장 좋지만, 미래에 대한 자체 모니터링을 위해 서버 자체에 어떤 기능을 내장하고 싶습니다. – Dima

+1

편집하십시오. JVM이 어떤 파일을 열 었는지 알려줄 수는 없다고 생각합니다. Sun이 추가 할 수있는 좋은 기능 일 수도 있지만 그때까지는 외부 프로세스를 사용해야 만 알 수 있습니다. JVM 내부에서 실제로 필요하다면 lsof를 실행하고 결과를 리턴하는 코드를 작성하십시오. 또한 열린 파일의 한도를 변경할 수 있습니다. 예를 들어 Linux에서는 /etc/security/limits.conf 파일을 수정할 수 있습니다. – bramp

답변

27

당신은 당신이 실행되는 OS 말을하지 않았다,하지만 당신은 리눅스에서 실행되는 경우는 lsof를 명령 JVM에 의해 열린 모든 파일을 나열합니다

lsof -p <pid of jvm> 

를 사용할 수 있습니다. 또는 Windows에서 실행중인 경우 Process Explorer을 사용하면 모든 프로세스의 모든 열린 파일을 볼 수 있습니다.

이 작업을 수행하면 파일의 어느 비트를 열어 두는 지 알 수 있습니다.

+0

좋은 아이디어. 'lsof'에 전달할 수있는 플래그를 확인하여 매 X 초마다 반복합니다. – Timothy

+0

Linixes에 대한 의견을 추가했습니다. lsof 팁에 감사드립니다! – Dima

+2

내 솔루션이 문제를 추적하는 데 도움이되는지 알고 싶습니다. 또한 기밀 사항이 아니거나 많은 번거 로움이 있다면 결국 문제의 원인을 설명 할 수 있습니까? – bramp

23

Linux를 사용하고 있으므로/proc-Filesystem을 확인하는 것이 좋습니다. proc 내부에는 calld 'fd'폴더를 포함하는 프로세스의 PID를 가진 폴더가 있습니다. 당신의 프로세스 ID가 1234 인 경우, 경로 (마십시오 'LS -l'), 당신이 열려있는 모든 파일에 대한 링크를 찾을 해당 폴더 내부

/proc/1234/fd 

수 있습니다. 일반적으로 어떤 라이브러리/코드가 열리 며 파일을 닫지 않을지 파일 이름으로 알 수 있습니다.

+0

감사합니다.이 파일은 유용하지만 파일 시스템이나 OS를 파고 들지는 않습니다. JVM 프로세스가 왜 "아프다"는 것을 말해 주길 원합니다. 사용자가 두통을 앓고있는 것이 잘못된 것이라는 이유가 있기를 바랍니다. – Dima

10

당신은 /etc/security/limits.conf에 다음을 추가하여 연 파일의 제한을 변경할 수 있습니다

* soft nofile 2048 # Set the limit according to your needs 
* hard nofile 2048 

그런 다음 당신은 쉘에 sysctl -p를 사용하여 구성을 다시로드 할 수 있습니다. this article을 확인하십시오. ulimit -n

10

그래서, 전체 응답 (나는 @phisch 및 @bramp 답변을 결합) :

그냥 완성도를 위해 당신은 사용하여 열 파일에 대한 전류 제한이 무엇인지 확인할 수 있습니다. 모든 프로세스를 확인하려면 sudo을 사용해야합니다. 또한 결과를 파일에 저장하는 것이 좋습니다. lsof는 저렴하지는 않지만이 파일은 추가 조사에 유용 할 수 있습니다.

sudo lsof > lsof.log 

보기 나쁜 놈들 : 파일 기술자의

cat lsof.log | awk '{ print $2 " " $1; }' | sort -rn | uniq -c | sort -rn | head -5 

    2687 114970 java 
    131 127992 nginx 
    109 128005 nginx 
    105 127994 nginx 
    103 128019 nginx 

리스트 저장뿐만 아니라 파일에 :

sudo ls -l /proc/114970/fd > fd.log 

표시 위로 열려있는 파일 :

cat fd | awk '{ print $11 }' | sort -rn | uniq -c | sort -rn | head -n20 
+2

대단히 감사합니다. 정말 유용합니다! 제 생각에는 3 번째 명령을 잊어 버린 것 같습니다 : sudo ls -l/proc/114970/fd> fd.log' – ocramot

+0

@ocramot, 여러분 환영합니다! 추신. 당신이 옳았어요, 제 대답을 고쳤습니다. – Jimilian

관련 문제