2008-09-01 2 views
5

JDK 1.5.0_08이 적용된 Fedora Core 6에서 실행되는 응용 프로그램에 문제가 있습니다.여러 스레드가 네이티브 호출에 걸림 (Java)

가동 시간 중 일부 (보통 며칠간)가 원시 메소드에서 멈추기 시작한 후에.

스레드

는 다음과 같이 뭔가에 고정되어 VM의 때까지 갇혀 남아

"HealthMonitor-10" daemon prio=1 tid=0x0868d1c0 nid=0x2b72 waiting for monitor entry [0xbe5ff000..0xbe5ff4d4] 
at java.lang.Thread.dumpThreads(Native Method) 
at java.lang.Thread.getStackTrace(Thread.java:1383) 

스레드 :

"pool-2-thread-2571" prio=1 tid=0x08dd0b28 nid=0x319e waiting for monitor entry [0xb91fe000..0xb91ff7d4] 
at java.lang.Class.getDeclaredConstructors0(Native Method) 

또는

"pool-2-thread-2547" prio=1 tid=0x75641620 nid=0x1745 waiting for monitor entry [0xbc7fe000..0xbc7ff554] 
at sun.misc.Unsafe.defineClass(Native Method) 

특히 나에게 수수께끼

이 하나입니다 다시 시작됩니다.

아무도 내게 무슨 일이 일어나고 있는지, 네이티브 메소드가 차단할 수있는 원인을 알려 줄 수 있습니까? 각 고정 스레드의 맨 위에있는 모니터 항목 주소 범위가 다릅니다. 이 모니터를 보유하고있는 것이 무엇인지 어떻게 알 수 있습니까?

모든 제안이나 조언을 부탁드립니다!

덕분에, 데이비드

답변

0

은 아마 당신은 다른 JDK 버전을 사용해야합니다.
"수수께끼 하나"의 경우 1.5.0_08에 대한 버그 항목이 있습니다. 메모리 누수가 (이이 문제에 관련이 있는지 나는 모른다)보고됩니다
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6469701

은 또한 소스 코드를 얻을 볼 수 있었다, 다른 측면에서 라인 1383.에서 무슨 일이 수 원래 오류가 발생한 후에 스택 덤프가됩니다.

+0

...이 스레드 여기에 모든 시간을 갇히지, 그러나 희망 여기에 정보가 가능한 원인이 배제 적어도 다른 사람을 도움이됩니다의 근본 원인이 될 것입니다 말할 수 없습니다 I 않는 한 나중에 문제가 해결 된 JDK 버전의 버그로 인해 문제가 있음을 입증 할 수 있습니다. JDK 업그레이드는 옵션이 아닙니다. 내일 소스 코드를 살펴 보도록하겠습니다. 문제에 대한 통찰력을 얻을 수 있기를 바랍니다. JDK 네이티브 스택 트레이스를 보여주고 거기에 아무것도 볼 수없는 "혼합 네이티브/자바"쓰레드 덤프를 생각해 보았지만 ... 저는 리눅스에서 실행 중이므로 링크 된 버그는 관련성이 있습니다. –

4

처음에는 내 생각 엔 당신이 어떤 종류의 클래스 로더가 deadlock을 리얼하게 경험하고있을 것입니다. 클래스 정보는 처음로드 된 스레드뿐만 아니라 전체 VM에서 사용할 수 있기 때문에 일부 클래스에서는 클래스 로딩을 동기화해야한다고 생각합니다.

스택 맨 위에있는 메서드가 기본 메서드라는 사실은 클래스 로딩 메커니즘의 일부가 그런 식으로 구현되기 때문에 순수한 우연한 것처럼 보입니다.

나는 클래스 로딩 현명한 작업에 대해 더 자세히 조사 할 것이다. 어쩌면 일부 스레드는 클래스 로더를 사용하여 속도가 느리고 사용할 수없는 네트워크 위치에서 클래스를로드하므로 클래스를로드하려는 다른 스레드로 모니터를 전송하지 않고 실제로 오랜 시간 동안 차단합니다. -verbose : class를 사용하여 JVM을 시작할 때 출력을 조사하면 시도 할 수있는 한 가지 일 수 있습니다.

2

몇 달 전에 비슷한 문제가 있었는데 jthread (?) 유틸리티가 매우 유용하다는 것을 알았습니다. Java 응용 프로그램의 프로세스 ID를 지정하면 프로세스의 각 스레드에 대해 전체 스택을 덤프합니다.

jthread의 출력에서 ​​하나의 스레드가 모니터에 들어간 후에 잠금을 얻으려고하고 다른 스레드가 잠금을 획득 한 후 모니터에 들어가려고한다는 것을 알 수있었습니다. 교착 상태에 대한 처방.

응용 프로그램이 가비지 수집 문제로 실행되고 있는지 궁금합니다. 너는 그것이 이렇게 멈추기 전에 그것이 며칠 동안 달린다 고 말한다.어쩌면 GC가 끝났는지 확인하기 위해 얼마나 오래 붙어있는 상태에있게 했습니까?

+1

도구 이름이 jstack이라고 생각합니다. 위의 스레드 정보에 사용했습니다. 또한 SIGQUIT (ctrl - \\)를 JVM에 보내는 것은 스레드를 stdout으로 덤프합니다. 내 문제는 교착 상태가 내 제어 (원시 코드) 이상의 코드에서 발생하고있는 것 같습니다. 나는 의심의 여지가 있지만 어떻게 든 자물쇠를 들고있어 ... –

1

네이티브 메소드가 대기중인 모니터에서 실제로 어떤 스레드가 동기화되고 있는지 확인할 수 있습니까? 당신은 당신이 그것에게 SIGQUIT를 보낼 때 VM에서 얻을 적어도 스레드 덤프 (죽일 -3)이 정보를 표시해야합니다, 당신은 지금까지 게시 한 덤프에서

"Thread-0" prio=5 tid=0x0100b060 nid=0x84c000 waiting for monitor entry [0xb0c8a000..0xb0c8ad90] 
    at Deadlock$1.run(Deadlock.java:8) 
    - waiting to lock <0x255e5b38> (a java.lang.Object) 
... 
"main" prio=5 tid=0x01001350 nid=0xb0801000 waiting on condition [0xb07ff000..0xb0800148] 
    at java.lang.Thread.sleep(Native Method) 
    at Deadlock.main(Deadlock.java:21) 
- locked <0x255e5b38> (a java.lang.Object) 

같이 내가 할 수있는 ' 특정 모니터를 잠그기 위해 실제로 대기중인 스레드를 보지 마십시오 ...

+0

나는 당신이 그것에 대해 클래스 로더 관련이 있다고 생각한다. 비록 스레드가 항상 네이티브 메소드를 막기는하지만, 우연이라고는 생각하지 않습니다. 로드하는 데 시간이 오래 걸리거나 사용할 수없는 클래스는 없습니다. 클래스 경로에는 로컬 항아리 만 포함됩니다. 실제로는 하나 이상의 클래스 로더가 있으며, 각 클래스는 일부 리소스에 대해 경합하여 결과적으로 차단 될 수 있습니다. Groovy 사용이 응용 프로그램에서 제거되었으므로 (PermGen에서 메모리 누수가 발생 함) 블록의 추가 사례를 발견하지 못했습니다. 이것이 문제의 원인이 될 수 있습니다. –

+0

불행히도, 분명히 교착 상태 모니터가 없습니다. 모니터를 식별하는 어떤 값도 스레드 덤프에서 반복되지 않습니다. 내가 눈치 챘을 경우 : JVM이 교착 상태가 의심되는 스레드를보고하고 스레드 덤프에서 문제를 찾는 데 도움이되는 [Thread Dump Analyzer] [1] visualvm 플러그인이 있다고 생각합니다. –

0

같은 문제 (Tomcat 6.0.29가 설치된 Linux에서 실행되는 JDK 1.6.0_23)를 치고 나서이 스레드를 발견했습니다. 그 비트가 관련이 있는지 모르지만 - 내가 알아챈 것은 많은 스레드가 getDeclaredConstructors() 네이티브 메소드에 "붙어있는"것을 제외하고는 CPU가 Java 프로세스에서 100 %였습니다. 그래서 모든 요청 스레드가 여기서 멈추고, CPU가 100 %에 이르며, 스레드 덤프가 교착 상태를 보이지 않고 (중요한 작업을 수행하는 다른 스레드가 없음) 나에게 쓰레기 수집기와 같은 냄새가났다. 물론 충분히, 서버 로그를 검사하고 많은 OutOfMemory 오류가있었습니다 - 힙 공간이 모두 소모되었습니다.

관련 문제