2017-03-28 67 views
0

我使用tomcat服務器,當我拿到線程轉儲我可以看到許多線程被阻塞(172)和其他線程IN_NATIVE(27)。幾乎很多堵塞的線程就像下面的smiler。有人能幫助什麼可能是原因嗎?我的8GB OldGen空間已滿。執行GC後也不釋放。許多線程被阻塞,並從老根存儲器不釋放

阻塞的線程:

Thread 22614 - threadId:Thread 22614 - state:BLOCKED 
stackTrace: 
- java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise) 
- java.net.SocketInputStream.read(byte[], int, int, int) @bci=87, line=152 (Compiled frame) 
- java.net.SocketInputStream.read(byte[], int, int) @bci=11, line=122 (Compiled frame) 
- org.apache.coyote.http11.InternalInputBuffer.fill(boolean) @bci=59, line=512 (Compiled frame) 
- org.apache.coyote.http11.InternalInputBuffer.fill() @bci=2, line=497 (Compiled frame) 
- org.apache.coyote.http11.Http11Processor.process(org.apache.tomcat.util.net.SocketWrapper) @bci=263, line=203 (Compiled frame) 
- org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(org.apache.tomcat.util.net.SocketWrapper, org.apache.tomcat.util.net.SocketStatus) @bci=96, line=515 (Compiled frame) 
- org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run() @bci=130, line=302 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=95, line=1145 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame) 
- java.lang.Thread.run() @bci=11, line=745 (Interpreted frame) 




Thread 23677 - threadId:Thread 23677 - state:BLOCKED 
stackTrace: 
- sun.misc.Unsafe.park(boolean, long) @bci=0 (Compiled frame; information may be imprecise) 
- java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long) @bci=20, line=226 (Compiled frame) 
- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long) @bci=68, line=2082 (Compiled frame) 
- java.util.concurrent.LinkedBlockingQueue.poll(long, java.util.concurrent.TimeUnit) @bci=62, line=467 (Compiled frame) 
- org.apache.tomcat.util.threads.TaskQueue.poll(long, java.util.concurrent.TimeUnit) @bci=3, line=86 (Compiled frame) 
- org.apache.tomcat.util.threads.TaskQueue.poll(long, java.util.concurrent.TimeUnit) @bci=3, line=32 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor.getTask() @bci=141, line=1068 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1130 (Compiled frame) 
- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame) 
- java.lang.Thread.run() @bci=11, line=745 (Interpreted frame) 


Thread 23674 - threadId:Thread 23674 - state:BLOCKED 
stackTrace: 
- com.mysql.jdbc.SingleByteCharsetConverter.toString(byte[], int, int) @bci=1, line=322 (Compiled frame) 
- com.mysql.jdbc.ResultSetRow.getString(java.lang.String, com.mysql.jdbc.MySQLConnection, byte[], int, int) @bci=54, line=797 (Compiled frame) 
- com.mysql.jdbc.ByteArrayRow.getString(int, java.lang.String, com.mysql.jdbc.MySQLConnection) @bci=24, line=72 (Compiled frame) 
- com.mysql.jdbc.ResultSetImpl.getStringInternal(int, boolean) @bci=155, line=5699 (Compiled frame) 
- com.mysql.jdbc.ResultSetImpl.getString(int) @bci=3, line=5576 (Compiled frame) 
- com.mysql.jdbc.ResultSetImpl.getString(java.lang.String) @bci=6, line=5616 (Compiled frame) 
- com.mchange.v2.c3p0.impl.NewProxyResultSet.getString(java.lang.String) @bci=19, line=3342 (Compiled frame) 
- org.hibernate.type.StringType.get(java.sql.ResultSet, java.lang.String) @bci=2, line=41 (Compiled frame) 
- org.hibernate.type.NullableType.nullSafeGet(java.sql.ResultSet, java.lang.String) @bci=3, line=184 (Compiled frame) 
- org.hibernate.type.NullableType.nullSafeGet(java.sql.ResultSet, java.lang.String, org.hibernate.engine.SessionImplementor, java.lang.Object) @bci=3, line=210 (Compiled frame) 
+0

嗯,線程轉儲似乎並不準確。 'Unsafe.park'是一個TIMED_WAITING,並且socket.read正在等待。你能通過'kill -3 '生成一個線程轉儲嗎?它將包含阻塞線程的對象的地址,因此您可以檢查是否存在死鎖。 – bashnesnos

回答

1
  • 首先堆棧跟蹤表明線程試圖從套接字讀取走進BLOCKED狀態。套接字讀取操作是一個阻塞操作,這意味着如果沒有什麼要讀取或者直到所有的信息都被完全讀取,它將被阻塞。

  • 其次,LinkedBlockingQueue.poll()不是一個阻塞操作,所以這是一個正常的堆棧跟蹤來指示通常的空閒線程。這不是由用戶代碼造成的

  • 第三,由於返回結果集中的字符串值,這也不會造成問題。

我想,你應該看看this了。

堆棧跟蹤#1和#3可能相關,因爲套接字讀取可能是數據庫讀取。

這些堆棧跟蹤不會幫助解決問題,但是這些被阻塞的線程只是表示內存過多和垃圾收集過多的問題。

您的C3P0池可能存在問題,或者您可能會創建語句和結果集對象 - 總而言之,這似乎是內存泄漏和資源關閉不良的情況。

如果沒有相關的應用程序代碼,非常精確的答案是不可能的。另外,如評論中所述,鎖定對象的身份也需要轉儲。

希望它有幫助!