2017-03-28 8 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은 소켓 읽기가 DB 읽기 일 수 있으므로 관련 될 수 있습니다.

이러한 스택 추적은 문제를 해결하는 데는 도움이되지 않지만 이러한 종류의 차단 된 스레드는 단순히 너무 많은 메모리 및 과도한 가비지 수집 문제를 나타냅니다.

C3P0 풀 또는 문 및 결과 집합 개체를 만드는 방식에 문제가있을 수 있습니다. 모두 메모리 누수와 리소스가 제대로 닫히지 않는 것 같습니다.

관련 애플리케이션 코드가 없으면 매우 정확한 대답을 할 수 없습니다. 또한 주석에 명시된 바와 같이 잠금 객체의 ID도 덤프해야합니다.

희망이 있습니다!