如何正确处理SSLSocketImpl死锁?

时间:2014-08-03 10:26:00

标签: java wikipedia-api

使用wiki-java时很少遇到死锁。看一下完整的线程转储(通过kill -3 $JAVA-PID获得)表明死锁似乎是源自SSLSocketImpl中的某个地方。我宁愿首先避免这种僵局(而不是做一些hacky恢复),但我不确定如何找到原因并阻止它。有没有办法在SSLSocketImpl中设置超时或在死锁的情况下抛出异常? (在主循环中捕获它并重做最后一次调用会非常简单)

Full thread dump OpenJDK 64-Bit Server VM (24.51-b03 mixed mode):

"Service Thread" daemon prio=10 tid=0x00007f3cd816b000 nid=0x102c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" daemon prio=10 tid=0x00007f3cd8168800 nid=0x102b waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" daemon prio=10 tid=0x00007f3cd8165800 nid=0x102a waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00007f3cd8163800 nid=0x1029 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00007f3cd8140800 nid=0x1028 waiting on condition [0x00007f3ccb9f7000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007d77a9080> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:799)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:672)
        at sun.security.ssl.SSLSocketImpl.sendAlert(SSLSocketImpl.java:2005)
        at sun.security.ssl.SSLSocketImpl.warning(SSLSocketImpl.java:1832)
        at sun.security.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1600)
        - locked <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1538)
        at sun.security.ssl.BaseSSLSocketImpl.finalize(BaseSSLSocketImpl.java:249)
        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
        at java.lang.ref.Finalizer.access$100(Finalizer.java:32)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190)

"Reference Handler" daemon prio=10 tid=0x00007f3cd813e800 nid=0x1027 in Object.wait() [0x00007f3ccbaf9000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000078495a2c8> (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 <0x000000078495a2c8> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0x00007f3cd8008000 nid=0x1021 waiting for monitor entry [0x00007f3cdfdb7000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at sun.security.ssl.SSLSocketImpl.getConnectionState(SSLSocketImpl.java:649)
        - waiting to lock <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.isClosed(SSLSocketImpl.java:1446)
        at java.net.Socket.getTcpNoDelay(Socket.java:965)
        at sun.security.ssl.BaseSSLSocketImpl.getTcpNoDelay(BaseSSLSocketImpl.java:345)
        at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:819)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:801)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
        - locked <0x00000007d77a8d60> (a sun.security.ssl.AppOutputStream)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        - locked <0x00000007d77a8d48> (a java.io.BufferedOutputStream)
        at java.io.PrintStream.flush(PrintStream.java:338)
        - locked <0x00000007d77a8d28> (a java.io.PrintStream)
        at sun.net.www.MessageHeader.print(MessageHeader.java:297)
        - locked <0x00000007d6d057b0> (a sun.net.www.MessageHeader)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:599)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:610)
        at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:619)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1321)
        - locked <0x00000007d6d05640> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
        at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:2731)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:307)
        at shared.Wiki.grabCookies(Wiki.java:6907)
        at shared.Wiki.fetch(Wiki.java:6462)
        at shared.Wiki.getPageText(Wiki.java:1465)
        at smallBots.Bot1.getText(Bot1.java:204)
        at smallBots.Bot1.crawlCategory(Bot1.java:74)
        at smallBots.Bot1.main(Bot1.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

"VM Thread" prio=10 tid=0x00007f3cd813a000 nid=0x1026 runnable 

"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f3cd801d800 nid=0x1022 runnable 

"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f3cd801f800 nid=0x1023 runnable 

"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f3cd8021800 nid=0x1024 runnable 

"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f3cd8023000 nid=0x1025 runnable 

"VM Periodic Task Thread" prio=10 tid=0x00007f3cd8175800 nid=0x102d waiting on condition 

JNI global references: 205


Found one Java-level deadlock:
=============================
"Finalizer":
  waiting for ownable synchronizer 0x00000007d77a9080, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
  which is held by "main"
"main":
  waiting to lock monitor 0x00007f3cac0015c8 (object 0x00000007d77a8d78, a sun.security.ssl.SSLSocketImpl),
  which is held by "Finalizer"

Java stack information for the threads listed above:
===================================================
"Finalizer":
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007d77a9080> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:799)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:672)
        at sun.security.ssl.SSLSocketImpl.sendAlert(SSLSocketImpl.java:2005)
        at sun.security.ssl.SSLSocketImpl.warning(SSLSocketImpl.java:1832)
        at sun.security.ssl.SSLSocketImpl.closeInternal(SSLSocketImpl.java:1600)
        - locked <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.close(SSLSocketImpl.java:1538)
        at sun.security.ssl.BaseSSLSocketImpl.finalize(BaseSSLSocketImpl.java:249)
        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:101)
        at java.lang.ref.Finalizer.access$100(Finalizer.java:32)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:190)
"main":
        at sun.security.ssl.SSLSocketImpl.getConnectionState(SSLSocketImpl.java:649)
        - waiting to lock <0x00000007d77a8d78> (a sun.security.ssl.SSLSocketImpl)
        at sun.security.ssl.SSLSocketImpl.isClosed(SSLSocketImpl.java:1446)
        at java.net.Socket.getTcpNoDelay(Socket.java:965)
        at sun.security.ssl.BaseSSLSocketImpl.getTcpNoDelay(BaseSSLSocketImpl.java:345)
        at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:819)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:801)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
        - locked <0x00000007d77a8d60> (a sun.security.ssl.AppOutputStream)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        - locked <0x00000007d77a8d48> (a java.io.BufferedOutputStream)
        at java.io.PrintStream.flush(PrintStream.java:338)
        - locked <0x00000007d77a8d28> (a java.io.PrintStream)
        at sun.net.www.MessageHeader.print(MessageHeader.java:297)
        - locked <0x00000007d6d057b0> (a sun.net.www.MessageHeader)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:599)
        at sun.net.www.http.HttpClient.writeRequests(HttpClient.java:610)
        at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:619)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1321)
        - locked <0x00000007d6d05640> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
        at sun.net.www.protocol.http.HttpURLConnection.getHeaderFieldKey(HttpURLConnection.java:2731)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getHeaderFieldKey(HttpsURLConnectionImpl.java:307)
        at shared.Wiki.grabCookies(Wiki.java:6907)
        at shared.Wiki.fetch(Wiki.java:6462)
        at shared.Wiki.getPageText(Wiki.java:1465)
        at smallBots.Bot1.getText(Bot1.java:204)
        at smallBots.Bot1.crawlCategory(Bot1.java:74)
        at smallBots.Bot1.main(Bot1.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

Found 1 deadlock.

Heap
 PSYoungGen      total 10752K, used 801K [0x00000007d6d00000, 0x00000007d7880000, 0x0000000800000000)
  eden space 9728K, 1% used [0x00000007d6d00000,0x00000007d6d1fc20,0x00000007d7680000)
  from space 1024K, 65% used [0x00000007d7780000,0x00000007d7828b40,0x00000007d7880000)
  to   space 1024K, 0% used [0x00000007d7680000,0x00000007d7680000,0x00000007d7780000)
 ParOldGen       total 93696K, used 69956K [0x0000000784800000, 0x000000078a380000, 0x00000007d6d00000)
  object space 93696K, 74% used [0x0000000784800000,0x0000000788c51160,0x000000078a380000)
 PSPermGen       total 21504K, used 9537K [0x000000077a200000, 0x000000077b700000, 0x0000000784800000)
  object space 21504K, 44% used [0x000000077a200000,0x000000077ab50720,0x000000077b700000)

1 个答案:

答案 0 :(得分:1)

提问者回答:更新到Java 8以修复它。