On 3/28/2018 6:28 PM, 이의준 wrote:
Test sequence and inquiry contents

1. In the local test, the same load (hp-jmeter) for tomcat 7, 8 5 minutes,

2. Thread dump generated after 5 minutes of load termination

3. Most Thread in Tomcat 7 is in TIME_WAITING state (normally OK)

4. Thread in Tomcat 8 mostly RUNNABLE state (estimated to be abnormal)

      Thread Final Stack - Below (reading something)

      at org.apache.tomcat.jni.Socket.recvbb (Native Method)

I'm not an expert by any means.  I have only an elementary understanding of what the combined information on a thread dump says about system health.

Presumably if the server is not busy, most of the threads will be idle, waiting for something to do.  Whether threads that are "idle" will show up as runnable or waiting will depend on the *exact* part of the code that the thread is running at the moment of the dump.

I would imagine that if a thread can be kept in a runnable state instead of a waiting state while it is doing "nothing" and waiting for work, that thread will probably respond faster when the work actually arrives.  If the thread is in a waiting state, Java probably has to explicitly tell the thread to wake up before it will begin processing.

Looking at your actual stacktraces, I see that the Tomcat 8 thread is sitting at "org.apache.tomcat.jni.Socket.recvbb(Native Method)".  Tomcat 7 is sitting at "sun.misc.Unsafe.park(Native Method)", and indicates that it is waiting on a lock object -- it says "parking to wait for  <0x0000000083769178> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)" right after the first line of the stacktrace.

Documentation about the "recvbb" method says that this is the method that receives a block of data from the network.  And the stacktrace says that it is a "native" method -- which I am reasonably certain means that it is compiled native code for the CPU that isn't actually part of Java.  If I'm correct about that, it means that the "do nothing" part of this code is completely outside Java.  As far as Java is concerned, that thread is running, not waiting, because the pause is not being handled by Java.

For Tomcat 7, the thread is running Java code only, and it is using Java's locking mechanisms to keep the thread in a "paused" state.  Java actually knows that the thread is waiting.  The Unsafe.park method IS native code, but it is native code that's actually part of Java, so Java is able to detect precisely what it's doing.

The native code is more efficient than the Java code.  When a block of data finally arrives from the network, the native code can process that data very quickly and return control to Java on a thread that is *already* in a runnable state.  The Tomcat 7 code must go through the process of releasing and acquiring a lock before that thread can resume executing.  The time difference on a single request would be undetectable by a person, but for systems with high utilization, that difference could affect how much hardware is required to handle a certain request load.

Native libraries are available for both Tomcat versions.

https://tomcat.apache.org/tomcat-7.0-doc/apr.html

If you were to install/activate the native library for Tomcat 7, I bet that version would have very similar thread dumps to Tomcat 8.

Thanks,
Shawn


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to