방금 Jstack을 사용하여 프로세스 교착 상태의 문제를 해결했습니다. 실제로는 오래 전에 해결했지만 그 이유를 알고 있지만 교착 상태의 위치를 찾지 못했기 때문에 그렇게하지 않습니다.
프로세스는 대략 다음과 같습니다.
(0) 환경 요구 사항, JDK 1.6 이상
(1) 먼저 프로세스의 PID를 찾으십시오. Windows에서 프로세스 관리자를 열고 이름으로 정렬하십시오. Javaw.exe라는 프로세스를 찾을 수 있습니다 (Java Virtual Machine 프로세스는 모두 javaw.exe라고합니다). 프로세스인지 프로세스를 찾아 현재 프로세스 목록을 기억 한 다음 프로세스를 다시 시작해야합니다. PID에 의해 새로 고침 된 것은 프로세스입니다.
(2) CMD에 따라 실행 : Jstack PID, JSTACK은 콘솔에 일련의 정보를 입력합니다.
(3) 위의 정보를 분석하십시오
예:
내 질문에 대한 JSTACK 정보는 다음과 같습니다.
C :/문서 및 설정/사용자> JSTACK 66522012-06-07 21 : 32 : 02 풀 스레드 덤프 Java Hotspot (TM) 클라이언트 VM (16.3-B01 혼합 모드, 공유) : "스레드 -1"DEAMON PRIO = 6 TID = 0X03010C00 NID = 0XCDC 모니터 입력 대기 [0X039F000] java.lang.thread.state : org.apache.commons.net.telnet.telnetinputstream .__ read (TelnetInputStream.java:122)에서 차단 (객체 모니터) - <0x22942280> (org.apache.commons.ftp.ftpclient) at at <0x22942280> (<0x22942280> <0x22942280> org.apache.commons.net.telnet.telnetinputstream.run (java.lang.lang.thread.run (thread.java:619)의 un (telnetinputstream.java:535) "프레임 워크 이벤트 디스패처"Daemon prio = 6 tid = 0x030400 nid = 0x998 In 객체 (0x033). java.lang.thread.state : java.lang.object.wait (기본 메소드)에서 대기 (객체 모니터) - 대기중인 <0x228fa800> (a org.eclipse.osgi.framework.eventmgr.eventmgr.eventmanager $ eventthread) at java.lang.obit.wait (object.java:485). org.eclipse.osgi.framework.eventmgr.eventmanager $ eventthread.getnextevent (eventmanager.java:400) - 잠금 <0x228fa800> (org.eclipse.osgi.framework.eventMgr.eventManager $ eventThread) at org.eclipse.osgi.framework.eventmgr.eventmanager $ eventthread.run (eventmanager.java:336) "시작 레벨 이벤트 디스패처"daemon prio = 6 tid = 0x02fcf400 nid = 0x2638 in object.wait () [0x032de000] java.lang. java.lang.object.wait (기본 메소드) - <0x2295db48> (a [i) at java.lang.object.wait (object.java:485) at org.apache.commons.net.telnet.telnetinputstream.read (telnetinputstream.java:339) -joked <0x229) - (a [i) org.apache.commons.net.telnet.telnetinputstream.read (java.io.bufferedinputstream.read1 at java.io.io.io.io.buferedinputestream.read (bufferedpeceperedinputestream.java.31) 잠금 <0x2295fe18> (java.io.bufferedInputStream)에서 sun.nio.cs.streamdecoder.readbytes (streamdecoder.java:264)의 sun.nio.cs.impllead (streamdecoder.java:306) at sun.nio.cs.streamdecoder.read (streamdecoder.java:158) - 잠금 <0x22961f88> (java.io.inputstreamreader)에서 <0x22961f88> (java.io.inputstreamreader) java.io.bufferedReader.fill (bufferedReader.java:136) at java.io.bufferedReader.Readline (bufferedReader.java:299) - 잠금 <0x22961f88> (ajava.io.inputStreamreader) java.io.bufferedReader.readline (bufferedReader.java:362) at org.apache.commons.net.ftp.ftp .__ getreply (ftp.java:264) at org.apache.commons.net.ftp.ftp._connectaction_ (ftp.java:335) at org.apache.commons.net.ftp.ftpclient._connectaction_ (ftpclient.java:550) at org.apache.commons.net.socketclient.connect (socketclient.java:163)의 com.mycompany.dc.ftp.client.cclients. -com.mycompany.dc.ftp.client.ftpclientfactoryimpl.getClient (ftpclientsfictoryimpl.java:35) - 잠금 <0x228f9310> (java.lang). ftpclientStest.activator.start (activer.java:43) at org.eclipse.osgi.framework.internal.core.bundlecontextimpl $ 1.Run (bundLeconTextImpl.java:711) at java.security.accesscontroller.dprovileged (방법) at org.eclipse.osgi.framework.internal.core.bundlecontextimpl.startActivator (bundlecontextimpl.java:702) at org.eclipse.osgi.framework.internal.core.bundlecontextimpl.start (bundleconxt.java:683) org.eclipse.osgi.framework.internal.core.bundlehost.startworker (bondlehost.java:381) at org.eclipse.osgi.framework.internal.core.abstractbundle.resume (AbstractBundle.java:389) org.eclipse.osgi.framework.internal.core.framework.resumebundle (framework.java:1131) at org.eclipse.osgi.framework.internal.core.startlevelmanager.resumebundles (StartlevelManager.java:559) at org.eclipse.osgi.framework.internal.core.startlevelmanager.resumebundles (startlevelmanager.java:544) at org.eclipse.osgi.framework.internal.core.startlevelmanager.incfwsl (startlevelmanager.java:457) at org.eclipse.osgi.framework.internal.core.startlevelmanager.dosetstartlevel (startlevelmanager.java:243) - 잠금 <0x27e68d70> (java.lang.object) at org.eclipse.osgi.framework.internal.core.startlevelmanager.dispatchevent (startlevelmanager.java:438) at org.eclipse.osgi.framework.internal.core.startlevelmanager.dispatchevent (startlevelmanager.java:1) at org.eclipse.osgi.framework.eventmgr.eventmanger.eventmanager.dispatchevent (eventmanager.java:230) at org.eclipse.osgi.framework.eventmgr.eventmanager $ eventThread.run (eventmanager.java:340) "프리오 = 6 TifiD"0xword " object.wait () [0x0328f000] java.lang.thread.state : java.lang.object.wait (기본 메소드)의 timed_waiting (객체 모니터) - <0x27e65770> (a org.eclipse.osgi.famwork.famework..famwork..famwork..famework..famework..famework.camerore)에서 nid = 0x1fbc. org.eclipse.osgi.framework.internal.core.framework.run (framework.java:1817) - 잠금 <0x27e65770> (a org.eclipse.osgi.framework.internal.core.framwork) at java.lang.thread.threang.threat.thrun (thread.java:619) "" prio = 6 tid = 0x03005400 nid = 0x225c 조건에서 대기 대기 [0x0323f000] java.lang.thread.state : java.lang.sleep.sleep (기본 메소드)에서 timed_waiting (수면). org.eclipse.osgi.framework.internal.core.frameworkConsole.runconsole (frameworkConsole.java:125) at org.eclipse.osgi.framework.internal.core.frameworkConsole.run (FrameworkConsole.javea:104) at java.lang.thread.run (Thread.java:619) "낮은 메모리 탐지기"Daemon Prio = 6 TID = 0x1d68 runnable [0x000000000] java.lang.state : runnable "compilerthread0" "Daemon Prio = 10 tid = 0x02c03000 nid = 조건 [0x000000000] java.lang.thread.state : runnable "첨부 청취자"데몬 프리오 = 10 TID = 0x1138 NID = 0x1138 조건에서 대기 대기 [0x000000000] java.lang.thread.state : runnable "신호 디스패처"10 tid = 0x02c20c20c20c20c20c20c20c20c20c20 [0x000000000] java.lang.thread.state : runnable "finalizer"daemon prio = 8 tid = 0x11ac in object.wait () [0x02d8f000] java.lang.thread.state : java.lang.wait에서 대기 모니터에서 대기 (대기) 대기 (대기). <0x27d5e5c8> (java.lang.ref.ref.ref.ref.ref.refferiqueue.refferende.remove (referencequeue.java:118) - 잠금 <0x27d5e5c8> (java.lang.ref.referionue $)에서 잠금. java.lang.ref.ref.ref.ref.ref (referencequeue.java:134) at java.lang.ref.finalizer $ finalizerthread.run (finalizer.java:159) "참조 핸들러"devon prio = 10 tid = 0x02bb800 nid = 0x9cc in object.wait () [0x02d3f000] java.lang.thread.state : java.lang.object.wait (기본 메소드)에서 대기 (객체 모니터) - 대기 대기 <0x27d5e650> (java.lang.ref.reference $ lock)에서 java.lang.object.wait (object.java:485) at. java.lang.ref.reference $ reforehhandler.run (reference.java:116) - 잠금 <0x27d5e650> (java.lang.ref.reference $ lock) "main"prio = 6 tid = 0x008a6c00 nid = 0x22ec in object.wait () [0x0098f000] java.lang. java.lang.object.wait (기본 메소드)에서 timed_waiting (객체 모니터) - <0x22c303c8> (a org.eclipse.core.internal.adaptor.semaphore)에서 대기 중입니다. 잠금 <0x22c303c8> (org.eclipse.internal.adaptor.semaphore) at ang.eclipse.core.runtime.eclipsestarter.updatesplash (eclipsestarter.java:1251) org.eclipse.core.runtime.adaptor.eclipsestarter.clipstarter.setstartlevel (eclipsestarter.java:1213) at org.eclipse.core.runtime.eclipsestarter.startup (eclipsTarter.java:288) at org.eclipse.core.runtime.adaptor.eclipsestarter.run (sun.reflect.nativemethodaccessorimpl.invoke0에서 sun.reflect.natovemedaccessorimpl.invevoke sun.reflect.delegatingMethodaccessorimpl.invoke (java.lang.reflect.method.invoke (method.java:597)에서 java.eclipse.lecinox.make.makeworkwork (main.java:622)의 java.lang.reflect.invoke (method.java:597)를 위임합니다 org.eclipse.equinox.launcher.main.basicrun (main.java:577) at org.eclipse.equinox.launcher.main.run (main.java:1410) at org.eclipse.equinox.launcher.main.main (main.java:1386) "vm stled"10 TID = 0x02BBA000 NID = 0xDB4 RUNNABLE "VM 주기성 작업 스레드"PRIO = 10 TID = 0x02C0E400 NID = 0x24AC 조건에서 대기 대기 조건 전역 참조 : 677
분석 :
프롬프트에 따르면, 두 스레드는 FTPClient 객체를 잠금으로 사용하고 잠금 장치를 얻는 이전의 스레드는 잠금의 리턴 결과가 필요할 때까지 잠금 장치를 기다려야하므로 교착 상태가 발생합니다. 이 두 곳은 다음과 같습니다.
(1) org.apache.commons.net.telnet.telnetinputstream .__ read (telnetinputstr
eam.java:122)
(2) - 잠금 <0x22942280> (a org.apache.commons.net.ftp.ftpclient)
com.sagemcom.dc.ftp.client.ftpclientfactoryimpl.getClient (ftpclientfa
ctoryimpl.java:35)
- 잠겨 <0x228f9310> (java.lang.object)
전자는 시스템 자체가 사용하는 잠금 장치이며 후자는 내 코드에 추가됩니다. 자체 코드의 객체를 변경하여 잠그면 해결됩니다.
요약
Jstack은 문제 해결에 매우 도움이됩니다. 정보는 간결하고 효과적입니다. 실제로, 그것에 기반한 많은 그래픽 분석 도구가 있습니다. 그러나 JSTACK은 JDK1.6 이상의 지원을 받아야합니다.
위는 JSTACK 분석을 통해 프로세스 교착 문제 해결에 대한이 기사의 전체 내용입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!