[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-serviceability-dev
Subject:    Re: RFR: 8185005: Improve performance of ThreadMXBean.getThreadInfo(long ids[], int maxDepth)
From:       "serguei.spitsyn () oracle ! com" <serguei ! spitsyn () oracle ! com>
Date:       2019-07-29 9:12:01
Message-ID: 65e52a11-21b3-58d2-a707-c7ecdc8bcff7 () oracle ! com
[Download RAW message or body]

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Hi Daniil,<br>
      <br>
      Probably, it'd make sense to re-iterate on this after you resolve
      David's comments.<br>
      Now, just one comment though as it looks dangerous.<br>
      <br>
<a class="moz-txt-link-freetext" \
href="http://cr.openjdk.java.net/~dtitov/8185005/webrev.03/src/hotspot/share/services/ \
management.cpp.udiff.html">http://cr.openjdk.java.net/~dtitov/8185005/webrev.03/src/hotspot/share/services/management.cpp.udiff.html</a><br>
  <br>
      <pre>       } else {
         // reset contention statistics for a given thread
<span class="new">+        JavaThread* java_thread = NULL;</span>
<span class="new">+        if (THREAD-&gt;is_Java_thread()) {</span>
<span class="new">+          JavaThread* current_thread = (JavaThread*)THREAD;</span>
<span class="new">+          if (tid == \
java_lang_Thread::thread_id(current_thread-&gt;threadObj())) {</span> <span \
class="new">+            java_thread = current_thread;</span> <span class="new">+     \
}</span> <span class="new">+        }</span>
<span class="new">+        if (java_thread == NULL) {</span>
         JavaThread* java_thread = \
jtiwh.list()-&gt;find_JavaThread_from_java_tid(tid); <span class="new">+        \
}</span>  if (java_thread == NULL) {
           return false;
         }
</pre>
      Now, the definition of java_thread
      below:<br>
      <pre><span class="new">+        if (java_thread == NULL) {</span>
           JavaThread* java_thread = \
jtiwh.list()-&gt;find_JavaThread_from_java_tid(tid); <span class="new">+        \
}</span></pre>  <br>
      becomes completely useless because the block of its definition is
      ended right away.<br>
      Here, overriding the local variable <span class="new">'java_thread'
        does not look as a good idea.<br>
      </span>  <br>
      Then how was it really tested?<br>
      <br>
      Thanks,<br>
      Serguei<br>
      <br>
      <br>
      <br>
      <br>
      <br>
      On 7/24/19 10:21, Daniil Titov wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:76BCC96D-DB5D-409A-95D5-3A64B893832D@oracle.com">
      <pre class="moz-quote-pre" wrap="">Hi David, Daniel, and Serguei,

Please review the new version of the fix, that makes the thread table initialization \
on demand and  moves it inside ThreadsList::find_JavaThread_from_java_tid(). At the \
creation time the thread table  is initialized with the threads from the current \
thread list. We don't want to hold Threads_lock  inside \
find_JavaThread_from_java_tid(),  thus new threads still could be created  while the \
thread table is being initialized . Such threads will be found by the linear search \
and added to the thread table later, in ThreadsList::find_JavaThread_from_java_tid().

The change also includes additional optimization for some callers of \
find_JavaThread_from_java_tid() as Daniel suggested. 

That is correct that ResolvedMethodTable was used as a blueprint for the thread \
table, however, I tried to strip it of the all functionality that is not required in \
the thread table case.

We need to have the thread table resizable and allow it to grow as the number of \
threads increases to avoid   reserving excessive memory a-priori or deteriorating \
lookup times. The ServiceThread is responsible for growing the thread table when \
required.

There is no ConcurrentHashTable available in Java 8 and for backporting this fix to \
Java 8 another implementation  of the hash table, probably originally suggested in \
the patch attached to the JBS issue, should be used.  It will make the backporting \
more complicated,  however, adding a new Implementation of the hash table in Java 14 \
while it  already has ConcurrentHashTable doesn't seem  reasonable for me.


Webrev: <a class="moz-txt-link-freetext" \
href="http://cr.openjdk.java.net/~dtitov/8185005/webrev.03">http://cr.openjdk.java.net/~dtitov/8185005/webrev.03</a>
                
Bug: <a class="moz-txt-link-freetext" \
href="https://bugs.openjdk.java.net/browse/JDK-8185005">https://bugs.openjdk.java.net/browse/JDK-8185005</a> \


Thanks!
--Daniil


On 7/8/19, 3:24 PM, "Daniel D. Daugherty" <a class="moz-txt-link-rfc2396E" \
href="mailto:daniel.daugherty@oracle.com">&lt;daniel.daugherty@oracle.com&gt;</a> \
wrote:

    On 6/29/19 12:06 PM, Daniil Titov wrote:
    &gt; Hi Serguei and David,
    &gt;
    &gt; Serguei is right, ThreadTable::find_thread(java_tid) cannot  return a \
JavaThread with an unmatched java_tid.  &gt;
    &gt; Please find a new version of the fix that includes the changes Serguei \
suggested.  &gt;
    &gt; Regarding the concern about the maintaining the thread table when it may \
never even be queried, one of  &gt; the options could be to add ThreadTable \
::isEnabled flag, set it to "false" by default, and wrap the calls to the thread \
table  &gt; in ThreadsSMRSupport add_thread() and remove_thread() methods to check \
this flag.  &gt;
    &gt; When ThreadsList::find_JavaThread_from_java_tid() is called for the first \
time it could check if ThreadTable ::isEnabled  &gt; Is on and if not then set it on \
and populate the thread table with all existing threads from the thread list.  
    I have the same concerns as David H. about this new ThreadTable.
    ThreadsList::find_JavaThread_from_java_tid() is only called from code
    in src/hotspot/share/services/management.cpp so I think that table
    needs to enabled and populated only if it is going to be used.
    
    I've taken a look at the webrev below and I see that David has
    followed up with additional comments. Before I do a crawl through
    code review for this, I would like to see the ThreadTable stuff
    made optional and David's other comments addressed.
    
    Another possible optimization is for callers of
    find_JavaThread_from_java_tid() to save the calling thread's
    tid value before they loop and if the current tid == saved_tid
    then use the current JavaThread* instead of calling
    find_JavaThread_from_java_tid() to get the JavaThread*.
    
    Dan
    
    &gt;
    &gt; Webrev: <a class="moz-txt-link-freetext" \
href="https://cr.openjdk.java.net/~dtitov/8185005/webrev.02/">https://cr.openjdk.java.net/~dtitov/8185005/webrev.02/</a>
  &gt; Bug: <a class="moz-txt-link-freetext" \
href="https://bugs.openjdk.java.net/browse/JDK-8185005">https://bugs.openjdk.java.net/browse/JDK-8185005</a>
  &gt;
    &gt; Thanks!
    &gt; --Daniil
    &gt;
    &gt; From: <a class="moz-txt-link-rfc2396E" \
href="mailto:serguei.spitsyn@oracle.com">&lt;serguei.spitsyn@oracle.com&gt;</a>  &gt; \
Organization: Oracle Corporation  &gt; Date: Friday, June 28, 2019 at 7:56 PM
    &gt; To: Daniil Titov <a class="moz-txt-link-rfc2396E" \
href="mailto:daniil.x.titov@oracle.com">&lt;daniil.x.titov@oracle.com&gt;</a>, \
OpenJDK Serviceability <a class="moz-txt-link-rfc2396E" \
href="mailto:serviceability-dev@openjdk.java.net">&lt;serviceability-dev@openjdk.java.net&gt;</a>, \
<a class="moz-txt-link-rfc2396E" \
href="mailto:hotspot-runtime-dev@openjdk.java.net">"hotspot-runtime-dev@openjdk.java.net"</a> \
<a class="moz-txt-link-rfc2396E" \
href="mailto:hotspot-runtime-dev@openjdk.java.net">&lt;hotspot-runtime-dev@openjdk.java.net&gt;</a>, \
<a class="moz-txt-link-rfc2396E" \
href="mailto:jmx-dev@openjdk.java.net">"jmx-dev@openjdk.java.net"</a> <a \
class="moz-txt-link-rfc2396E" \
href="mailto:jmx-dev@openjdk.java.net">&lt;jmx-dev@openjdk.java.net&gt;</a>  &gt; \
Subject: Re: RFR: 8185005: Improve performance of ThreadMXBean.getThreadInfo(long \
ids[], int maxDepth)  &gt;
    &gt; Hi Daniil,
    &gt;
    &gt; I have several quick comments.
    &gt;
    &gt; The indent in the hotspot c/c++ files has to be 2, not 4.
    &gt;
    &gt; <a class="moz-txt-link-freetext" \
href="https://cr.openjdk.java.net/~dtitov/8185005/webrev.01/src/hotspot/share/runtime/ \
threadSMR.cpp.frames.html">https://cr.openjdk.java.net/~dtitov/8185005/webrev.01/src/hotspot/share/runtime/threadSMR.cpp.frames.html</a>
  &gt; 614 JavaThread* ThreadsList::find_JavaThread_from_java_tid(jlong java_tid) \
const {  &gt;   615     JavaThread* java_thread = ThreadTable::find_thread(java_tid);
    &gt;   616     if (java_thread == NULL &amp;&amp; java_tid == \
PMIMORDIAL_JAVA_TID) {  &gt;   617         // ThreadsSMRSupport::add_thread() is not \
called for the primordial  &gt;   618         // thread. Thus, we find this thread \
with a linear search and add it  &gt;   619         // to the thread table.
    &gt;   620         for (uint i = 0; i &lt; length(); i++) {
    &gt;   621             JavaThread* thread = thread_at(i);
    &gt;   622             if (is_valid_java_thread(java_tid,thread)) {
    &gt;   623                 ThreadTable::add_thread(java_tid, thread);
    &gt;   624                 return thread;
    &gt;   625             }
    &gt;   626         }
    &gt;   627     } else if (java_thread != NULL &amp;&amp; \
is_valid_java_thread(java_tid, java_thread)) {  &gt;   628         return \
java_thread;  &gt;   629     }
    &gt;   630     return NULL;
    &gt;   631 }
    &gt;   632 bool ThreadsList::is_valid_java_thread(jlong java_tid, JavaThread* \
java_thread) {  &gt;   633     oop tobj = java_thread-&gt;threadObj();
    &gt;   634     // Ignore the thread if it hasn't run yet, has exited
    &gt;   635     // or is starting to exit.
    &gt;   636     return (tobj != NULL &amp;&amp; !java_thread-&gt;is_exiting() \
&amp;&amp;  &gt;   637             java_tid == java_lang_Thread::thread_id(tobj));
    &gt;   638 }
    &gt;
    &gt;   615     JavaThread* java_thread = ThreadTable::find_thread(java_tid);
    &gt;
    &gt;    I'd suggest to rename find_thread() to find_thread_by_tid().
    &gt;
    &gt; A space is missed after the comma:
    &gt;    622 if (is_valid_java_thread(java_tid,thread)) {
    &gt;
    &gt; An empty line is needed before L632.
    &gt;
    &gt; The name 'is_valid_java_thread' looks wrong (or confusing) to me.
    &gt; Something like 'is_alive_java_thread_with_tid()' would be better.
    &gt; It'd better to list parameters in the opposite order.
    &gt;
    &gt; The call to is_valid_java_thread() is confusing:
    &gt;     627 } else if (java_thread != NULL &amp;&amp; \
is_valid_java_thread(java_tid, java_thread)) {  &gt;
    &gt; Why would the call ThreadTable::find_thread(java_tid) return a JavaThread \
with an unmatched java_tid?  &gt;
    &gt;   
    &gt; Thanks,
    &gt; Serguei
    &gt;
    &gt; On 6/28/19, 9:40 PM, "David Holmes" <a class="moz-txt-link-rfc2396E" \
href="mailto:david.holmes@oracle.com">&lt;david.holmes@oracle.com&gt;</a> wrote:  \
&gt;  &gt;      Hi Daniil,
    &gt;      
    &gt;      The definition and use of this hashtable (yet another hashtable
    &gt;      implementation!) will need careful examination. We have to be concerned
    &gt;      about the cost of maintaining it when it may never even be queried. You
    &gt;      would need to look at footprint cost and performance impact.
    &gt;      
    &gt;      Unfortunately I'm just about to board a plane and will be out for the
    &gt;      next few days. I will try to look at this asap next week, but we will
    &gt;      need a lot more data on it.
    &gt;      
    &gt;      Thanks,
    &gt;      David
    &gt;
    &gt; On 6/28/19 3:31 PM, Daniil Titov wrote:
    &gt; Please review the change that improves performance of ThreadMXBean MXBean \
methods returning the  &gt; information for specific threads. The change introduces \
the thread table that uses ConcurrentHashTable  &gt; to store one-to-one the mapping \
between the thread ids and JavaThread objects and replaces the linear  &gt; search \
over the thread list in ThreadsList::find_JavaThread_from_java_tid(jlong tid) method \
with the lookup  &gt; in the thread table.
    &gt;
    &gt; Testing: Mach5 tier1,tier2 and tier3 tests successfully passed.
    &gt;
    &gt; Webrev: <a class="moz-txt-link-freetext" \
href="https://cr.openjdk.java.net/~dtitov/8185005/webrev.01/">https://cr.openjdk.java.net/~dtitov/8185005/webrev.01/</a>
  &gt; Bug: <a class="moz-txt-link-freetext" \
href="https://bugs.openjdk.java.net/browse/JDK-8185005">https://bugs.openjdk.java.net/browse/JDK-8185005</a>
  &gt;
    &gt; Thanks!
    &gt;
    &gt; Best regards,
    &gt; Daniil
    &gt;
    &gt;
    &gt;
    &gt;
    &gt;
    &gt;
    &gt;
    
    


</pre>
    </blockquote>
    <br>
  </body>
</html>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic