### JDKèªå¸¦å½ä»¤jstackéè¿JVMå æ åæåºç°å¤§é线ç¨çåå ### æè¿æå¡å¨å åæ»æ¯èå ï¼äºæ¯æ³è¦åæä¸é®é¢çåå ï¼ é¦å æ¾å°JVMè¿ç¨ [root@10-13-40-54 social-search]# ps -aux | grep tomcat root 7437 5.8 8.0 10049732 1303772 pts/0 Sl 09:31 1:12 /usr/bin/java -Djava.util.logging.config.file=/usr/local/5080SocialSearchTomcat/conf/ logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs= /usr/local/5080SocialSearchTomcat/endorsed -classpath /usr/local/5080SocialSearchTomcat/bin/bootstrap.jar: /usr/local/5080SocialSearchTomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/5080SocialSearchTomcat -Dcatalina.home=/usr/local/5080SocialSearchTomcat -Djava.io.tmpdir=/usr/local/5080SocialSearchTomcat/ temp/org.apache.catalina.startup.Bootstrap start å¾å°JVMçtomcatè¿ç¨æ¯7437ï¼ç¶åæå æ 导åºï¼ä¸è½½å°æ¬å°ï¼ jstack -l 7437 > log.txt ä¸è½½åï¼åç°çº¿ç¨å æ ä¸ï¼æå¤§éçè¿æ ·çæ¥å¿ï¼ "pool-2918-thread-2" #14663 prio=5 os_prio=0 tid=0x00007fdc81759000 nid=0x157c waiting on condition [0x00007fd8821ef000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000079329da40 - > - (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) "pool-2918-thread-1" #14662 prio=5 os_prio=0 tid=0x00007fdc81757000 nid=0x157b waiting on condition [0x00007fd8822f0000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000079329da40> - (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) å¯ä»¥çå°ï¼çº¿ç¨å¤äºWAITINGç¶æï¼é»å¡å¨è¯å¾ä»ä»»å¡éåä¸åä»»å¡(LinkedBlockingQueue.take)ï¼è¿ä¸ªä»»å¡éåæçæ¯ThreadPoolExecutorççº¿ç¨æ± å¯å¨ç线ç¨ä»»å¡éåï¼ ä¹å°±æ¯è¯´ï¼è¿äºçº¿ç¨é½æ¯ç©ºé²ç¶æï¼å¨ççä»»å¡çå°æ¥å¢ï¼ è¡¥å ä¸LinkedBlockingQueueçç¥è¯ï¼ >å¹¶ååºä¸çBlockingQueueæ¯ä¸ä¸ªæ¯è¾å¥½ç©çç±»ï¼é¡¾åæä¹ï¼å°±æ¯é»å¡éåãè¯¥ç±»ä¸»è¦æä¾äºä¸¤ä¸ªæ¹æ³put()åtake()ï¼ >åè å°ä¸ä¸ªå¯¹è±¡æ¾å°éåå°¾é¨ï¼ >妿éåå·²ç»æ»¡äºï¼å°±çå¾ ç´å°æç©ºé²èç¹ï¼åè ä»headåä¸ä¸ªå¯¹è±¡ï¼å¦ææ²¡æå¯¹è±¡ï¼å°±çå¾ ç´å°æå¯åç对象ã å®ä½å°é®é¢å°±ç®åäºï¼æ¥æ¾ä»£ç ï¼åç°æä¸ªä½ç½®å¯å¨äºçº¿ç¨æ± æäº¤äºä»»å¡ï¼ä½æ¯ä»»å¡æ§è¡å®è¿ååï¼çº¿ç¨æ± 没æå ³é导è´çï¼ é®é¢æ»ç»ï¼ 1ã使ç¨ExecutorServiceæäº¤ç线ç¨ä»»å¡ï¼ä¹è¦è®°å¾å ³éï¼ 2ãå¯å¨æ°çº¿ç¨çæ¶åï¼æå¥½ç»çº¿ç¨èµ·ä¸ªååï¼è¿æ ·çº¿ç¨å æ çé®é¢ææ¥æ´å 容æï¼ ### å ³äºJstack ### #### ä¸ãä»ç» #### jstackæ¯javaèææºèªå¸¦çä¸ç§å æ è·è¸ªå·¥å ·ãjstackç¨äºæå°åºç»å®çjavaè¿ç¨IDæcore fileæè¿ç¨è°è¯æå¡çJavaå æ ä¿¡æ¯ï¼å¦ææ¯å¨64使ºå¨ä¸ï¼éè¦æå®é项"-J-d64"ï¼Windowsçjstackä½¿ç¨æ¹å¼åªæ¯æä»¥ä¸çè¿ç§æ¹å¼ï¼ jstack [-l] pid jstackç¨äºçæjavaèææºå½åæ¶å»ç线ç¨å¿«ç §ã线ç¨å¿«ç §æ¯å½åjavaèææºå æ¯ä¸æ¡çº¿ç¨æ£å¨æ§è¡çæ¹æ³å æ çéåï¼çæçº¿ç¨å¿«ç §ç主è¦ç®çæ¯å®ä½çº¿ç¨åºç°é¿æ¶é´åé¡¿çåå ï¼å¦çº¿ç¨é´æ»éãæ»å¾ªç¯ã请æ±å¤é¨èµæºå¯¼è´çé¿æ¶é´çå¾ çã 线ç¨åºç°åé¡¿çæ¶åéè¿jstackæ¥æ¥çå个线ç¨çè°ç¨å æ ï¼å°±å¯ä»¥ç¥é没æååºç线ç¨å°åºå¨åå°åä»ä¹äºæ ï¼æè çå¾ ä»ä¹èµæºã 妿javaç¨åºå´©æºçæcoreæä»¶ï¼jstackå·¥å ·å¯ä»¥ç¨æ¥è·å¾coreæä»¶çjava stackånative stackçä¿¡æ¯ï¼ä»èå¯ä»¥è½»æ¾å°ç¥éjavaç¨åºæ¯å¦ä½å´©æºåå¨ç¨åºä½å¤åçé®é¢ãå¦å¤ï¼jstackå·¥å ·è¿å¯ä»¥éå±å°æ£å¨è¿è¡çjavaç¨åºä¸ï¼çå°å½æ¶è¿è¡çjavaç¨åºçjava stackånative stackçä¿¡æ¯, 妿ç°å¨è¿è¡çjavaç¨åºåç°hungçç¶æï¼jstackæ¯é常æç¨çã So,jstackå½ä»¤ä¸»è¦ç¨æ¥æ¥çJava线ç¨çè°ç¨å æ çï¼å¯ä»¥ç¨æ¥åæçº¿ç¨é®é¢ï¼å¦æ»éï¼ #### 线ç¨ç¶æ #### æ³è¦éè¿jstackå½ä»¤æ¥åæçº¿ç¨çæ åµçè¯ï¼é¦å è¦ç¥é线ç¨é½æåªäºç¶æï¼ä¸é¢è¿äºç¶ææ¯æä»¬ä½¿ç¨jstackå½ä»¤æ¥ç线ç¨å æ ä¿¡æ¯æ¶å¯è½ä¼çå°ç线ç¨çå ç§ç¶æï¼ * NEW,æªå¯å¨çãä¸ä¼åºç°å¨Dumpä¸ã * RUNNABLE,å¨èææºå æ§è¡çã * BLOCKED,åé»å¡å¹¶çå¾ çè§å¨éã * WATING,æ éæçå¾ å¦ä¸ä¸ªçº¿ç¨æ§è¡ç¹å®æä½ã * TIMED_WATING,ææ¶éççå¾ å¦ä¸ä¸ªçº¿ç¨çç¹å®æä½ã * TERMINATED,å·²éåºçã #### Monitor #### å¨å¤çº¿ç¨ç JAVAç¨åºä¸ï¼å®ç°çº¿ç¨ä¹é´ç忥ï¼å°±è¦è¯´è¯´ Monitorã Monitoræ¯ Javaä¸ç¨ä»¥å®ç°çº¿ç¨ä¹é´çäºæ¥ä¸åä½çä¸»è¦ææ®µï¼å®å¯ä»¥çææ¯å¯¹è±¡æè Classçéãæ¯ä¸ä¸ªå¯¹è±¡é½æï¼ä¹ä» æä¸ä¸ª monitorãä¸ é¢è¿ä¸ªå¾ï¼æè¿°äºçº¿ç¨å Monitorä¹é´å ³ç³»ï¼ä»¥ å线ç¨çç¶æè½¬æ¢å¾ï¼  è¿å ¥åº(Entrt Set):表示线ç¨éè¿synchronizedè¦æ±è·å对象çéãå¦æå¯¹è±¡æªè¢«éä½,åè¿å ¥æ¥æè ;å¦ååå¨è¿å ¥åºçå¾ ã䏿¦å¯¹è±¡éè¢«å ¶ä»çº¿ç¨éæ¾,ç«å³åä¸ç«äºã æ¥æè (The Owner):表示æä¸çº¿ç¨æåç«äºå°å¯¹è±¡éã çå¾ åº(Wait Set):表示线ç¨éè¿å¯¹è±¡çwaitæ¹æ³,éæ¾å¯¹è±¡çé,å¹¶å¨çå¾ åºçå¾ è¢«å¤éã ä»å¾ä¸å¯ä»¥çåºï¼ä¸ä¸ª Monitorå¨æä¸ªæ¶å»ï¼åªè½è¢«ä¸ä¸ªçº¿ç¨æ¥æï¼è¯¥çº¿ç¨å°±æ¯ âActive Threadâï¼èå ¶å®çº¿ç¨é½æ¯ âWaiting Threadâï¼åå«å¨ä¸¤ä¸ªéå â Entry Setâå âWait Setâéé¢çåãå¨ âEntry Setâä¸çå¾ ç线ç¨ç¶ææ¯ âWaiting for monitor entryâï¼èå¨âWait Setâä¸çå¾ ç线ç¨ç¶ææ¯ âin Object.wait()âã å ç âEntry Setâéé¢ç线ç¨ãæä»¬ç§°è¢« synchronizedä¿æ¤èµ·æ¥çä»£ç æ®µä¸ºä¸´çåºãå½ä¸ä¸ªçº¿ç¨ç³è¯·è¿å ¥ä¸´çåºæ¶ï¼å®å°±è¿å ¥äº âEntry Setâéåã对åºç codeå°±åï¼ ```java synchronized(obj) { ... } ``` #### è°ç¨ä¿®é¥° #### * locked <å°å> ç®æ ï¼ä½¿ç¨synchronizedç³è¯·å¯¹è±¡éæå,çè§å¨çæ¥æè ã * waiting to lock <å°å> ç®æ ï¼ä½¿ç¨synchronizedç³è¯·å¯¹è±¡éæªæå,å¨è¿å ¥åºçå¾ ã * waiting on <å°å> ç®æ ï¼ä½¿ç¨synchronizedç³è¯·å¯¹è±¡éæåå,éæ¾éå¹µå¨çå¾ åºçå¾ ã * parking to wait for <å°å> ç®æ #### 1ãlocked #### at oracle.jdbc.driver.PhysicalConnection.prepareStatement - locked <0x00002aab63bf7f58> (a oracle.jdbc.driver.T4CConnection) at oracle.jdbc.driver.PhysicalConnection.prepareStatement - locked <0x00002aab63bf7f58> (a oracle.jdbc.driver.T4CConnection) at com.jiuqi.dna.core.internal.db.datasource.PooledConnection.prepareStatement éè¿synchronizedå ³é®å,æåè·åå°äºå¯¹è±¡çé,æä¸ºçè§å¨çæ¥æè ,å¨ä¸´çåºå æä½ãå¯¹è±¡éæ¯å¯ä»¥çº¿ç¨éå ¥çã #### 2ãwaiting to lock #### at com.jiuqi.dna.core.impl.CacheHolder.isVisibleIn(CacheHolder.java:165) - waiting to lock <0x0000000097ba9aa8> (a CacheHolder) at com.jiuqi.dna.core.impl.CacheGroup$Index.findHolder at com.jiuqi.dna.core.impl.ContextImpl.find at com.jiuqi.dna.bap.basedata.common.util.BaseDataCenter.findInfo éè¿synchronizedå ³é®å,没æè·åå°äºå¯¹è±¡çé,线ç¨å¨çè§å¨çè¿å ¥åºçå¾ ãå¨è°ç¨æ é¡¶åºç°,线ç¨ç¶æä¸ºBlockedã #### 3ãwaiting on #### at java.lang.Object.wait(Native Method) - waiting on <0x00000000da2defb0> (a WorkingThread) at com.jiuqi.dna.core.impl.WorkingManager.getWorkToDo - locked <0x00000000da2defb0> (a WorkingThread) at com.jiuqi.dna.core.impl.WorkingThread.run éè¿synchronizedå ³é®å,æåè·åå°äºå¯¹è±¡çéå,è°ç¨äºwaitæ¹æ³,è¿å ¥å¯¹è±¡ççå¾ åºçå¾ ãå¨è°ç¨æ é¡¶åºç°,线ç¨ç¶æä¸ºWAITINGæTIMED_WATINGã #### 4ãparking to wait for #### parkæ¯åºæ¬ç线ç¨é»å¡åè¯,ä¸éè¿çè§å¨å¨å¯¹è±¡ä¸é»å¡ãéconcurrentå ä¼åºç°çæ°çæºå¶,ä¸synchronizedä½ç³»ä¸åã #### 线ç¨å¨ä½ #### 线ç¨ç¶æäº§ççåå ï¼ * runnable:ç¶æä¸è¬ä¸ºRUNNABLEã * in Object.wait():çå¾ åºçå¾ ,ç¶æä¸ºWAITINGæTIMED_WAITINGã * waiting for monitor entry:è¿å ¥åºçå¾ ,ç¶æä¸ºBLOCKEDã * waiting on condition:çå¾ åºçå¾ ã被parkã * sleeping:ä¼ç ç线ç¨,è°ç¨äºThread.sleep()ã Wait on condition è¯¥ç¶æåºç°å¨çº¿ç¨çå¾ æä¸ªæ¡ä»¶çåçãå ·ä½æ¯ä»ä¹åå ï¼å¯ä»¥ç»å stacktraceæ¥åæã æå¸¸è§çæ åµå°±æ¯çº¿ç¨å¤äºsleepç¶æï¼çå¾ è¢«å¤éã 常è§çæ åµè¿æçå¾ ç½ç»IOï¼å¨javaå¼å ¥nioä¹åï¼å¯¹äºæ¯ä¸ªç½ç»è¿æ¥ï¼é½æä¸ä¸ªå¯¹åºççº¿ç¨æ¥å¤çç½ç»ç读åæä½ï¼å³ä½¿æ²¡æå¯è¯»åçæ°æ®ï¼çº¿ç¨ä»ç¶é»å¡å¨è¯»åæä½ä¸ï¼è¿æ ·æå¯è½é æèµæºæµªè´¹ï¼èä¸ç»æä½ç³»ç»ç线ç¨è°åº¦ä¹å¸¦æ¥ååãå¨ NewIOééç¨äºæ°çæºå¶ï¼ç¼åçæå¡å¨ç¨åºçæ§è½å坿©å±æ§é½å¾å°æé«ã æ£çå¾ ç½ç»è¯»åï¼è¿å¯è½æ¯ä¸ä¸ªç½ç»ç¶é¢çå¾å ãå 为ç½ç»é»å¡å¯¼è´çº¿ç¨æ æ³æ§è¡ãä¸ç§æ 嵿¯ç½ç»é常å¿ï¼å 乿¶èäºææç带宽ï¼ä»ç¶æå¤§éæ°æ®çå¾ ç½ç»è¯» åï¼å¦ä¸ç§æ åµä¹å¯è½æ¯ç½ç»ç©ºé²ï¼ä½ç±äºè·¯ç±çé®é¢ï¼å¯¼è´å æ æ³æ£å¸¸çå°è¾¾ãæä»¥è¦ç»åç³»ç»çä¸äºæ§è½è§å¯å·¥å ·æ¥ç»¼ååæï¼æ¯å¦ netstatç»è®¡å使¶é´çåéå çæ°ç®ï¼å¦æå¾ææ¾è¶ è¿äºæå¨ç½ç»å¸¦å®½çéå¶ ; è§å¯ cpuçå©ç¨çï¼å¦æç³»ç»æç CPUæ¶é´ï¼ç¸å¯¹äºç¨æ·æç CPUæ¶é´æ¯ä¾è¾é«ï¼å¦æç¨åºè¿è¡å¨ Solaris 10å¹³å°ä¸ï¼å¯ä»¥ç¨ dtraceå·¥å ·çç³»ç»è°ç¨çæ åµï¼å¦æè§å¯å° read/writeçç³»ç»è°ç¨çæ¬¡æ°æè è¿è¡æ¶é´é¥é¥é¢å ï¼è¿äºé½æåç±äºç½ç»å¸¦å®½æé导è´çç½ç»ç¶é¢ãï¼æ¥èª[http://www.blogjava.net/jzone/articles/303979.html](http://www.blogjava.net/jzone/articles/303979.html)ï¼ ### äºãå½ä»¤æ ¼å¼ ### jstack [ option ] pid jstack [ option ] executable core jstack [ option ] [server-id@]remote-hostname-or-IP 常ç¨åæ°è¯´æ 1ï¼optionsï¼ executable Java executable from which the core dump was produced.(å¯è½æ¯äº§çcore dumpçjava坿§è¡ç¨åº) core å°è¢«æå°ä¿¡æ¯çcore dumpæä»¶ remote-hostname-or-IP è¿ç¨debugæå¡ç主æºåæip server-id å¯ä¸id,åå¦ä¸å°ä¸»æºä¸å¤ä¸ªè¿ç¨debugæå¡ 2ï¼åºæ¬åæ°ï¼ -F å½âjstack [-l] pidâæ²¡æç¸åºçæ¶åå¼ºå¶æå°æ ä¿¡æ¯ -l é¿å表. æå°å ³äºéçéå ä¿¡æ¯,ä¾å¦å±äºjava.util.concurrentçownable synchronizerså表. -m æå°javaånative c/c++æ¡æ¶çæææ ä¿¡æ¯. -h | -helpæå°å¸®å©ä¿¡æ¯ pid éè¦è¢«æå°é 置信æ¯çjavaè¿ç¨id,å¯ä»¥ç¨jpsæ¥è¯¢. ### ä¸ã使ç¨å®ä¾ ### 1ãjstack pid ~$ jps -ml org.apache.catalina.startup.Bootstrap ~$ jstack 5661 2013-04-16 21:09:27 Full thread dump Java HotSpot(TM) Server VM (20.10-b01 mixed mode): "Attach Listener" daemon prio=10 tid=0x70e95400 nid=0x2265 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "http-bio-8080-exec-20" daemon prio=10 tid=0x08a35800 nid=0x1d42 waiting on condition [0x70997000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x766a27b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:399) at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:104) at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:32) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:662) ........ ä¸è¬æ åµä¸ï¼éè¿jstackè¾åºç线ç¨ä¿¡æ¯ä¸»è¦å æ¬ï¼jvmèªèº«çº¿ç¨ãç¨æ·çº¿ç¨çãå ¶ä¸jvm线ç¨ä¼å¨jvmå¯å¨æ¶å°±ä¼åå¨ã对äºç¨æ·çº¿ç¨åæ¯å¨ç¨æ·è®¿é®æ¶æä¼çæã 2ãjstack æ¥ç线ç¨å ·ä½å¨åä»ä¹ï¼å¯çåºåªäºçº¿ç¨å¨é¿æ¶é´å ç¨CPUï¼å°½å¿«å®ä½é®é¢åè§£å³é®é¢ [http://www.iteye.com/topic/1114219](http://www.iteye.com/topic/1114219) 1.topæ¥æ¾åºåªä¸ªè¿ç¨æ¶èçcpué«ãæ§è¡topå½ä»¤ï¼é»è®¤æ¯è¿ç¨è§å¾ï¼å ¶ä¸PIDæ¯è¿ç¨å· 21125 co_ad2 18 0 1817m 776m 9712 S 3.3 4.9 12:03.24 java 5284 co_ad 21 0 3028m 2.5g 9432 S 1.0 16.3 6629:44 ja è¿éæä»¬åæ21125è¿ä¸ªjavaè¿ç¨ 2.topä¸shift+h æâHâæ¥æ¾åºåªä¸ªçº¿ç¨æ¶èçcpué« å è¾å ¥topï¼ç¶ååæshift+h æâHâï¼æ¤æ¶æå¼çæ¯çº¿ç¨è§å¾ï¼pid为线ç¨å· 21233 co_ad2 15 0 1807m 630m 9492 S 1.3 4.0 0:05.12 java 20503 co_ad2_s 15 0 1360m 560m 9176 S 0.3 3.6 0:46.72 java è¿éæä»¬åæ21233è¿ä¸ªçº¿ç¨ï¼å¹¶ä¸æ³¨æçæ¯ï¼è¿ä¸ªçº¿ç¨æ¯å±äº21125è¿ä¸ªè¿ç¨çã 3.使ç¨jstackå½ä»¤è¾åºè¿ä¸æ¶å»ççº¿ç¨æ ï¼ä¿åå°æä»¶ï¼å½å为jstack.logãæ³¨æï¼è¾åºçº¿ç¨æ åä¿åtopå½ä»¤å¿«ç §å°½éåæ¶è¿è¡ã ç±äºjstack.logæä»¶è®°å½ç线ç¨IDæ¯16è¿å¶ï¼éè¦å°topå½ä»¤å±ç¤ºç线ç¨å·è½¬æ¢ä¸º16è¿å¶ã 4. jstackæ¥æ¾è¿ä¸ªçº¿ç¨çä¿¡æ¯ jstack [è¿ç¨]|grep -A 10 [线ç¨ç16è¿å¶] å³ï¼ jstack 21125|grep -A 10 52f1 -A 10è¡¨ç¤ºæ¥æ¾å°æå¨è¡çå10è¡ã21233ç¨è®¡ç®å¨è½¬æ¢ä¸º16è¿å¶52f1ï¼æ³¨æåæ¯æ¯å°åã ç»æï¼ "http-8081-11" daemon prio=10 tid=0x00002aab049a1800 nid=0x52bb in Object.wait() [0x0000000042c75000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:416) å¨ç»æä¸æ¥æ¾52f1ï¼å¯çå°å½å线ç¨å¨åä»ä¹ã 3ã代ç ç¤ºä¾ ```java /** * @author hollis */ public class JStackDemo1 { public static void main(String[] args) { while (true) { //Do Nothing } } } ``` å æ¯æjpsæ¥çè¿ç¨å·ï¼ hollis@hos:~$ jps 29788 JStackDemo1 29834 Jps 22385 org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar ç¶å使ç¨jstack æ¥çå æ ä¿¡æ¯ï¼ hollis@hos:~$ jstack 29788 2015-04-17 23:47:31 ...æ¤å¤çç¥è¥å¹²å 容... "main" prio=10 tid=0x00007f197800a000 nid=0x7462 runnable [0x00007f197f7e1000] java.lang.Thread.State: RUNNABLE at javaCommand.JStackDemo1.main(JStackDemo1.java:7) æä»¬å¯ä»¥ä»è¿æ®µå æ ä¿¡æ¯ä¸çåºä»ä¹æ¥å¢ï¼æä»¬å¯ä»¥çå°ï¼å½åä¸å ±æä¸æ¡ç¨æ·çº§å«çº¿ç¨,线ç¨å¤äºrunnableç¶æï¼æ§è¡å°JStackDemo1.javaç第ä¸è¡ã çä¸é¢ä»£ç ï¼ ```java /** * @author hollis */ public class JStackDemo1 { public static void main(String[] args) { Thread thread = new Thread(new Thread1()); thread.start(); } } class Thread1 implements Runnable{ @Override public void run() { while(true){ System.out.println(1); } } } ``` 线ç¨å æ ä¿¡æ¯å¦ä¸ï¼ "Reference Handler" daemon prio=10 tid=0x00007fbbcc06e000 nid=0x286c in Object.wait() [0x00007fbbc8dfc000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0000000783e066e0> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:503) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133) - locked <0x0000000783e066e0> (a java.lang.ref.Reference$Lock) æä»¬è½çå°ï¼ > 线ç¨çç¶æï¼ WAITING 线ç¨çè°ç¨æ 线ç¨çå½åéä½çèµæºï¼ <0x0000000783e066e0> 线ç¨å½åçå¾ çèµæºï¼<0x0000000783e066e0> 为ä»ä¹åæ¶éä½ççå¾ åä¸ä¸ªèµæºï¼ > 线ç¨çæ§è¡ä¸ï¼å è·å¾äºè¿ä¸ªå¯¹è±¡ç Monitorï¼å¯¹åºäº locked <0x0000000783e066e0>ï¼ã彿§è¡å° obj.wait(), 线ç¨å³æ¾å¼äº Monitorçæææï¼è¿å ¥ âwait setâéåï¼å¯¹åºäº waiting on <0x0000000783e066e0> ï¼ã ### åãå¦ä½åæ ### #### 1ã线ç¨Dumpçåæ #### åå > ç»å代ç é è¯»çæ¨çãéè¦çº¿ç¨Dumpåæºç çç¸äºæ¨å¯¼åå°è¯ãé æBugçæ ¹æºå¾å¾ä¸ä¼å¨è°ç¨æ ä¸ç´æ¥ä½ç°,ä¸å®æ ¼å¤æ³¨æçº¿ç¨å½åè°ç¨ä¹åçææè°ç¨ã å ¥æç¹ è¿å ¥åºçå¾ "d&a-3588" daemon waiting for monitor entry [0x000000006e5d5000] java.lang.Thread.State: BLOCKED (on object monitor) at com.jiuqi.dna.bap.authority.service.UserService$LoginHandler.handle() - waiting to lock <0x0000000602f38e90> (a java.lang.Object) at com.jiuqi.dna.bap.authority.service.UserService$LoginHandler.handle() 线ç¨ç¶æBLOCKED,线ç¨å¨ä½wait on monitor entry,è°ç¨ä¿®é¥°waiting to lockæ»æ¯ä¸èµ·åºç°ã表示å¨ä»£ç 级å«å·²ç»åå¨å²çªçè°ç¨ãå¿ ç¶æé®é¢ç代ç ,éè¦å°½å¯è½åå°å ¶åçã 忥åé»å¡ ä¸ä¸ªçº¿ç¨éä½æå¯¹è±¡,大éå ¶ä»çº¿ç¨å¨è¯¥å¯¹è±¡ä¸çå¾ ã "blocker" runnable java.lang.Thread.State: RUNNABLE at com.jiuqi.hcl.javadump.Blocker$1.run(Blocker.java:23) - locked <0x00000000eb8eff68> (a java.lang.Object) "blockee-11" waiting for monitor entry java.lang.Thread.State: BLOCKED (on object monitor) at com.jiuqi.hcl.javadump.Blocker$2.run(Blocker.java:41) - waiting to lock <0x00000000eb8eff68> (a java.lang.Object) "blockee-86" waiting for monitor entry java.lang.Thread.State: BLOCKED (on object monitor) at com.jiuqi.hcl.javadump.Blocker$2.run(Blocker.java:41) - waiting to lock <0x00000000eb8eff68> (a java.lang.Object) æç»è¿è¡çIO IOæä½æ¯å¯ä»¥ä»¥RUNNABLEç¶æè¾¾æé»å¡ãä¾å¦:æ°æ®åºæ»éãç½ç»è¯»åã æ ¼å¤æ³¨æå¯¹IO线ç¨ççå®ç¶æçåæã ä¸è¬æ¥è¯´,被ææå°RUNNABLEçIOè°ç¨,齿¯æé®é¢çã 以ä¸å æ æ¾ç¤ºï¼ 线ç¨ç¶æä¸ºRUNNABLEã è°ç¨æ å¨SocketInputStreamæSocketImplä¸,socketRead0çæ¹æ³ã è°ç¨æ å å«äºjdbcç¸å ³çå ãå¾å¯è½åçäºæ°æ®åºæ»é "d&a-614" daemon prio=6 tid=0x0000000022f1f000 nid=0x37c8 runnable [0x0000000027cbd000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(Unknown Source) at oracle.net.ns.Packet.receive(Packet.java:240) at oracle.net.ns.DataPacket.receive(DataPacket.java:92) at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:172) at oracle.net.ns.NetInputStream.read(NetInputStream.java:117) at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1034) at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:588) å线ç¨è°åº¦çä¼ç æ£å¸¸ççº¿ç¨æ± çå¾ "d&a-131" in Object.wait() java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at com.jiuqi.dna.core.impl.WorkingManager.getWorkToDo(WorkingManager.java:322) - locked <0x0000000313f656f8> (a com.jiuqi.dna.core.impl.WorkingThread) at com.jiuqi.dna.core.impl.WorkingThread.run(WorkingThread.java:40) å¯çç线ç¨çå¾ "d&a-121" in Object.wait() java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at com.jiuqi.dna.core.impl.AcquirableAccessor.exclusive() - locked <0x00000003011678d8> (a com.jiuqi.dna.core.impl.CacheGroup) at com.jiuqi.dna.core.impl.Transaction.lock() å ¥æç¹æ»ç» wait on monitor entryï¼ è¢«é»å¡ç,è¯å®æé®é¢ runnable ï¼ æ³¨æIOçº¿ç¨ in Object.wait()ï¼ æ³¨æéçº¿ç¨æ± çå¾ #### 2ãæ»éåæ #### çè¿ç¨å¨æ§è¡è¿ç¨ä¸ï¼ç±äºç«äºèµæºæè ç±äºå½¼æ¤éä¿¡èé æçä¸ç§é»å¡çç°è±¡ï¼è¥æ å¤åä½ç¨ï¼å®ä»¬é½å°æ æ³æ¨è¿ä¸å»ãæ¤æ¶ç§°ç³»ç»å¤äºæ»éç¶ææç³»ç»äº§çäºæ»éï¼è¿äºæ°¸è¿å¨äºç¸çå¾ çè¿ç¨ç§°ä¸ºæ»éè¿ç¨ã 说ç½äºï¼æç°å¨æ³å鸡èçé¥¼ï¼æ¡å䏿¾ç鸡èå饼ï¼ä½æ¯æåæçæååæ¶å嫿¿èµ·äºé¸¡èåç ï¼ææéæ¿ç鸡èï¼ä½æ¯æéè¦ä»æéç饼ãä»æéæ¿ç饼ï¼ä½æ¯ä»æ³è¦ææéç鸡èãå°±è¿æ ·ï¼å¦æä¸è½åæ¶æ¿å°é¸¡èå饼ï¼é£æä»¬å°±ä¸è½ç»§ç»ååé¢çå·¥ä½ï¼å鸡èç饼ï¼ãæä»¥ï¼è¿å°±é æäºæ»éã ç䏿®µæ»éçç¨åºï¼ ```java package javaCommand; /** * @author hollis */ public class JStackDemo { public static void main(String[] args) { Thread t1 = new Thread(new DeadLockclass(true));//建ç«ä¸ä¸ªçº¿ç¨ Thread t2 = new Thread(new DeadLockclass(false));//建ç«å¦ä¸ä¸ªçº¿ç¨ t1.start();//å¯å¨ä¸ä¸ªçº¿ç¨ t2.start();//å¯å¨å¦ä¸ä¸ªçº¿ç¨ } } class DeadLockclass implements Runnable { public boolean falg;// æ§å¶çº¿ç¨ DeadLockclass(boolean falg) { this.falg = falg; } public void run() { /** * 妿falgçå¼ä¸ºtrueåè°ç¨t1çº¿ç¨ */ if (falg) { while (true) { synchronized (Suo.o1) { System.out.println("o1 " + Thread.currentThread().getName()); synchronized (Suo.o2) { System.out.println("o2 " + Thread.currentThread().getName()); } } } } /** * 妿falgçå¼ä¸ºfalseåè°ç¨t2çº¿ç¨ */ else { while (true) { synchronized (Suo.o2) { System.out.println("o2 " + Thread.currentThread().getName()); synchronized (Suo.o1) { System.out.println("o1 " + Thread.currentThread().getName()); } } } } } } class Suo { static Object o1 = new Object(); static Object o2 = new Object(); } ``` 彿å¯å¨è¯¥ç¨åºæ¶ï¼æä»¬åç°ï¼ç¨åºåªè¾åºäºä¸¤è¡å 容ï¼ç¶åç¨åºå°±ä¸åæå°å ¶å®çä¸è¥¿äºï¼ä½æ¯ç¨åºå¹¶æ²¡æåæ¢ãè¿æ ·å°±äº§çäºæ»éã å½çº¿ç¨1使ç¨synchronizedéä½äºo1çåæ¶ï¼çº¿ç¨2乿¯ç¨synchronizedéä½äºo2ãå½ä¸¤ä¸ªçº¿ç¨é½æ§è¡å®ç¬¬ä¸ä¸ªæå°ä»»å¡çæ¶åï¼çº¿ç¨1æ³éä½o2ï¼çº¿ç¨2æ³éä½o1ã使¯ï¼çº¿ç¨1å½åéço1ï¼çº¿ç¨2éço2ãæä»¥ä¸¤ä¸ªæ³æé½æ æ³ç»§ç»æ§è¡ä¸å»ï¼å°±é æäºæ»éã ç¶åï¼æä»¬ä½¿ç¨jstackæ¥çä¸ä¸çº¿ç¨å æ ä¿¡æ¯ï¼ Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x00007f0134003ae8 (object 0x00000007d6aa2c98, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x00007f0134006168 (object 0x00000007d6aa2ca8, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at javaCommand.DeadLockclass.run(JStackDemo.java:40) - waiting to lock <0x00000007d6aa2c98> (a java.lang.Object) - locked <0x00000007d6aa2ca8> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) "Thread-0": at javaCommand.DeadLockclass.run(JStackDemo.java:27) - waiting to lock <0x00000007d6aa2ca8> (a java.lang.Object) - locked <0x00000007d6aa2c98> (a java.lang.Object) at java.lang.Thread.run(Thread.java:745) Found 1 deadlock. ååï¼å æ åç徿æ¾ï¼å®åè¯æä»¬ Found one Java-level deadlockï¼ç¶åæåºé ææ»éç两个线ç¨çå 容ãç¶åï¼åéè¿ Java stack information for the threads listed aboveæ¥æ¾ç¤ºæ´è¯¦ç»çæ»éçä¿¡æ¯ã ä»è¯´: > Thread-1卿³è¦æ§è¡ç¬¬40è¡çæ¶åï¼å½åéä½äºèµæº<0x00000007d6aa2ca8>,使¯ä»å¨çå¾ èµæº<0x00000007d6aa2c98>Thread-0卿³è¦æ§è¡ç¬¬27è¡çæ¶åï¼å½åéä½äºèµæº<0x00000007d6aa2c98>,使¯ä»å¨çå¾ èµæº<0x00000007d6aa2ca8> ç±äºè¿ä¸¤ä¸ªçº¿ç¨é½ææèµæºï¼å¹¶ä¸é½éè¦å¯¹æ¹çèµæºï¼æä»¥é æäºæ»éã åå æä»¬æ¾å°äºï¼å°±å¯ä»¥å ·ä½é®é¢å ·ä½åæï¼è§£å³è¿ä¸ªæ»éäºã #### å ¶ä» #### èææºæ§è¡Full GCæ¶,ä¼é»å¡ææçç¨æ·çº¿ç¨ãå æ¤,峿¶è·åå°åæ¥éç线ç¨ä¹æå¯è½è¢«é»å¡ã 卿¥ç线ç¨Dumpæ¶,é¦å æ¥çå åä½¿ç¨æ åµã #### é¢ç¹GCé®é¢æå åæº¢åºé®é¢ #### ä¸ã使ç¨jpsæ¥ç线ç¨ID äºã使ç¨jstat -gc 3331 250 20 æ¥çgcæ åµï¼ä¸è¬æ¯è¾å ³æ³¨PERMåºçæ åµï¼æ¥çGCçå¢é¿æ åµã ä¸ã使ç¨jstat -gccauseï¼é¢å¤è¾åºä¸æ¬¡GCåå åã使ç¨jmap -dump:format=b,file=heapDump 3331çæå è½¬å¨æä»¶ äºã使ç¨jhatæè å¯è§åå·¥å ·ï¼Eclipse Memory Analyzer ãIBM HeapAnalyzerï¼åæå æ åµã å ãç»å代ç è§£å³å åæº¢åºææ³é²é®é¢ã #### æ»éé®é¢ #### ä¸ã使ç¨jpsæ¥ç线ç¨ID äºã使ç¨jstack 3331ï¼æ¥ççº¿ç¨æ åµ