Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8251498

JMX: Add a version of ThreadMXBean.dumpAllThreads with a maxDepth argument

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • openjdk8u282
    • core-svc
    • None
    • behavioral
    • minimal
    • Hide
      Addition to `com.sun.management.ThreadMXBean` of a variant of `java.lang.management.dumpAllThreads` and a variant of `java.lang.management.getThreadInfo`. Minimal risk since there can be no existing uses of the new methods.

      Note that c.s.m.ThreadMXBean extends j.l.m.ThreadMXBean, which in turn extends PlatformManagedObject. The Java 12 javadoc for the latter says

      "The platform MXBean interfaces (i.e. all subinterfaces of PlatformManagedObject) are implemented by the Java platform only. New methods may be added in these interfaces in future Java SE releases. In addition, this PlatformManagedObject interface is only intended for the management interfaces for the platform to extend but not for applications."

      In theory, this means that only platform (JDK library) code can extend c.s.m.ThreadMXBean, but until sealed types are implemented, it is still possible for user code to do so, hence the new dumpAllThreads and getThreadInfo methods must have default implementations, which in this case throw UnsupportedOperationException.
      Show
      Addition to `com.sun.management.ThreadMXBean` of a variant of `java.lang.management.dumpAllThreads` and a variant of `java.lang.management.getThreadInfo`. Minimal risk since there can be no existing uses of the new methods. Note that c.s.m.ThreadMXBean extends j.l.m.ThreadMXBean, which in turn extends PlatformManagedObject. The Java 12 javadoc for the latter says "The platform MXBean interfaces (i.e. all subinterfaces of PlatformManagedObject) are implemented by the Java platform only. New methods may be added in these interfaces in future Java SE releases. In addition, this PlatformManagedObject interface is only intended for the management interfaces for the platform to extend but not for applications." In theory, this means that only platform (JDK library) code can extend c.s.m.ThreadMXBean, but until sealed types are implemented, it is still possible for user code to do so, hence the new dumpAllThreads and getThreadInfo methods must have default implementations, which in this case throw UnsupportedOperationException.
    • Java API
    • JDK

      This is an 8u backport CSR of https://bugs.openjdk.java.net/browse/JDK-8185705. The original CSR specified the addition of two methods to java.lang.management.ThreadMXBean, so cannot be applied directly to Java 8 without an approved Java 8 update JSR. That will not happen for this kind of change, so this CSR instead adds the two methods to com.sun.management.ThreadMXBean. The package com.sun.management is JDK-specific and thus outside the scope of the Java SE 8 specification.

      Volker Simonis pointed out in https://mail.openjdk.java.net/pipermail/jdk8u-dev/2020-August/012557.html that when we backport a JMM feature, we are actually updating the existing JMM version specification rather than transitioning to a new one. There was a bit of recognition of this in https://bugs.openjdk.java.net/browse/JDK-8249101, where the @since javadoc tag was updated to 11.0.9 rather than 14. Imo, Volker makes a good argument for leaving the JMM version alone when doing JMM backports. So, we will

      1. In both jmm.h files (jdk and hotspot), leave JMM_VERSION at 0x20010203.
      2. Change the @since javadoc from '10' to '8u282'.

      The original CSR updated the javadoc of the pre-existing DumpAllThreads and getThreadInfo methods to refer to their new versions. We assume that cannot be done in for this backport, because a super-interface cannot reference a sub-interface, and com.sun.management.ThreadMXBean is a sub-interface of java.lang.management.ThreadMXBean. This CSR does not include the references, since it does not change the java.lang.management.ThreadMXBean javadoc.

      The original patch's javadoc uses @code to replace tt /tt pairs. The Java 8 javadoc uses the latter, so instances of @code have been replaced with the latter.

      The original javadoc for the new getThreadInfo method included the line

       *    <li>the <a href="LockInfo.html#OwnableSynchronizer">

      This does not work from com.sun.management.ThreadMXBean, so has been replaced by

       *    <li>the <a href="{@docRoot}/../api/java/lang/management/LockInfo.html#OwnableSynchronizer">

      Summary

      Add two new methods, com.sun.management.ThreadMXBean.dumpAllThreads and com.sun.management.ThreadMXBean.getThreadInfo, with a maxDepth argument to limit the stack trace depth.

      Problem

      Currently, java.lang.management.ThreadMXBean.dumpAllThreads and a version of java.lang.management.ThreadMXBean.getThreadInfo which includes lockedMonitors and lockedSynchronizers formal parameters, cannot limit returned stack trace depth as can another version of java.lang.management.ThreadMXBean.getThreadInfo. java.lang.management.ThreadMXBean.dumpAllThreads can therefore take excessive time/space for programs with thousands of threads.

      Solution

      Add two new methods, com.sun.management.ThreadMXBean.dumpAllThreads and com.sun.management.ThreadMXBean.getThreadInfo, each with a maxDepth argument to limit the stack trace depth.

      Specification

      /**                                                                                                                                                                                                                                                                                                                                                                     
       * Returns the thread info for each thread whose ID                                                                                                                                                                                                                                                                                                                     
       * is in the input array <tt>ids</tt>,                                                                                                                                                                                                                                                                                                                                  
       * with stack trace of the specified maximum number of elements                                                                                                                                                                                                                                                                                                         
       * and synchronization information.                                                                                                                                                                                                                                                                                                                                     
       * If <tt>maxDepth == 0</tt>, no stack trace of the thread                                                                                                                                                                                                                                                                                                              
       * will be dumped.                                                                                                                                                                                                                                                                                                                                                      
       *                                                                                                                                                                                                                                                                                                                                                                      
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * This method obtains a snapshot of the thread information                                                                                                                                                                                                                                                                                                             
       * for each thread including:                                                                                                                                                                                                                                                                                                                                           
       * <ul>                                                                                                                                                                                                                                                                                                                                                                 
       *    <li>stack trace of the specified maximum number of elements,</li>                                                                                                                                                                                                                                                                                                 
       *    <li>the object monitors currently locked by the thread                                                                                                                                                                                                                                                                                                            
       *        if <tt>lockedMonitors</tt> is <tt>true</tt>, and</li>                                                                                                                                                                                                                                                                                                         
       *    <li>the <a href="{@docRoot}/../api/java/lang/management/LockInfo.html#OwnableSynchronizer">                                                                                                                                                                                                                                                                       
       *        ownable synchronizers</a> currently locked by the thread                                                                                                                                                                                                                                                                                                      
       *        if <tt>lockedSynchronizers</tt> is <tt>true</tt>.</li>                                                                                                                                                                                                                                                                                                        
       * </ul>                                                                                                                                                                                                                                                                                                                                                                
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * This method returns an array of the <tt>ThreadInfo</tt> objects,                                                                                                                                                                                                                                                                                                     
       * each is the thread information about the thread with the same index                                                                                                                                                                                                                                                                                                  
       * as in the <tt>ids</tt> array.                                                                                                                                                                                                                                                                                                                                        
       * If a thread of the given ID is not alive or does not exist,                                                                                                                                                                                                                                                                                                          
       * <tt>null</tt> will be set in the corresponding element                                                                                                                                                                                                                                                                                                               
       * in the returned array.  A thread is alive if                                                                                                                                                                                                                                                                                                                         
       * it has been started and has not yet died.                                                                                                                                                                                                                                                                                                                            
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * If a thread does not lock any object monitor or <tt>lockedMonitors</tt>                                                                                                                                                                                                                                                                                              
       * is <tt>false</tt>, the returned <tt>ThreadInfo</tt> object will have an                                                                                                                                                                                                                                                                                              
       * empty <tt>MonitorInfo</tt> array.  Similarly, if a thread does not                                                                                                                                                                                                                                                                                                   
       * lock any synchronizer or <tt>lockedSynchronizers</tt> is <tt>false</tt>,                                                                                                                                                                                                                                                                                             
       * the returned <tt>ThreadInfo</tt> object                                                                                                                                                                                                                                                                                                                              
       * will have an empty <tt>LockInfo</tt> array.                                                                                                                                                                                                                                                                                                                          
       *                                                                                                                                                                                                                                                                                                                                                                      
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * When both <tt>lockedMonitors</tt> and <tt>lockedSynchronizers</tt>                                                                                                                                                                                                                                                                                                   
       * parameters are <tt>false</tt>, it is equivalent to calling:                                                                                                                                                                                                                                                                                                          
       * <blockquote><pre>                                                                                                                                                                                                                                                                                                                                                    
       *     {@link #getThreadInfo(long[], int)  getThreadInfo(ids, maxDepth)}                                                                                                                                                                                                                                                                                                
       * </pre></blockquote>                                                                                                                                                                                                                                                                                                                                                  
       *                                                                                                                                                                                                                                                                                                                                                                      
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * This method is designed for troubleshooting use, but not for                                                                                                                                                                                                                                                                                                         
       * synchronization control.  It might be an expensive operation.                                                                                                                                                                                                                                                                                                        
       *                                                                                                                                                                                                                                                                                                                                                                      
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * <b>MBeanServer access</b>:<br>                                                                                                                                                                                                                                                                                                                                       
       * The mapped type of <tt>ThreadInfo</tt> is                                                                                                                                                                                                                                                                                                                            
       * <tt>CompositeData</tt> with attributes as specified in the                                                                                                                                                                                                                                                                                                           
       * {@link ThreadInfo#from ThreadInfo.from} method.                                                                                                                                                                                                                                                                                                                      
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @implSpec The default implementation throws                                                                                                                                                                                                                                                                                                                          
       * <tt>UnsupportedOperationException</tt>.                                                                                                                                                                                                                                                                                                                              
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @param  ids an array of thread IDs.                                                                                                                                                                                                                                                                                                                                  
       * @param  lockedMonitors if <tt>true</tt>, retrieves all locked monitors.                                                                                                                                                                                                                                                                                              
       * @param  lockedSynchronizers if <tt>true</tt>, retrieves all locked                                                                                                                                                                                                                                                                                                   
       *             ownable synchronizers.                                                                                                                                                                                                                                                                                                                                   
       * @param  maxDepth indicates the maximum number of                                                                                                                                                                                                                                                                                                                     
       * {@link StackTraceElement} to be retrieved from the stack trace.                                                                                                                                                                                                                                                                                                      
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @return an array of the {@link ThreadInfo} objects, each containing                                                                                                                                                                                                                                                                                                  
       * information about a thread whose ID is in the corresponding                                                                                                                                                                                                                                                                                                          
       * element of the input array of IDs.                                                                                                                                                                                                                                                                                                                                   
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @throws IllegalArgumentException if <tt>maxDepth</tt> is negative.                                                                                                                                                                                                                                                                                                   
       * @throws java.lang.SecurityException if a security manager                                                                                                                                                                                                                                                                                                            
       *         exists and the caller does not have                                                                                                                                                                                                                                                                                                                          
       *         ManagementPermission("monitor").                                                                                                                                                                                                                                                                                                                             
       * @throws java.lang.UnsupportedOperationException                                                                                                                                                                                                                                                                                                                      
       *         <ul>                                                                                                                                                                                                                                                                                                                                                         
       *           <li>if <tt>lockedMonitors</tt> is <tt>true</tt> but                                                                                                                                                                                                                                                                                                        
       *               the Java virtual machine does not support monitoring                                                                                                                                                                                                                                                                                                   
       *               of {@linkplain #isObjectMonitorUsageSupported                                                                                                                                                                                                                                                                                                          
       *               object monitor usage}; or</li>                                                                                                                                                                                                                                                                                                                         
       *           <li>if <tt>lockedSynchronizers</tt> is <tt>true</tt> but                                                                                                                                                                                                                                                                                                   
       *               the Java virtual machine does not support monitoring                                                                                                                                                                                                                                                                                                   
       *               of {@linkplain #isSynchronizerUsageSupported                                                                                                                                                                                                                                                                                                           
       *               ownable synchronizer usage}.</li>                                                                                                                                                                                                                                                                                                                      
       *         </ul>                                                                                                                                                                                                                                                                                                                                                        
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @see #isObjectMonitorUsageSupported                                                                                                                                                                                                                                                                                                                                  
       * @see #isSynchronizerUsageSupported                                                                                                                                                                                                                                                                                                                                   
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @since 8u282                                                                                                                                                                                                                                                                                                                                                         
       */
      
      public default ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors,
                                                boolean lockedSynchronizers, int maxDepth) {
          throw new UnsupportedOperationException();
      }
      
      /**
       * Returns the thread info for all live threads
       * with stack trace of the specified maximum number of elements
       * and synchronization information.
       * If <tt>maxDepth == 0</tt>, no stack trace of the thread                                                                                                                                                                                                                                                                                                              
       * will be dumped.                                                                                                                                                                                                                                                                                                                                                      
       * Some threads included in the returned array                                                                                                                                                                                                                                                                                                                          
       * may have been terminated when this method returns.                                                                                                                                                                                                                                                                                                                   
       *                                                                                                                                                                                                                                                                                                                                                                      
       * <p>                                                                                                                                                                                                                                                                                                                                                                  
       * This method returns an array of {@link ThreadInfo} objects                                                                                                                                                                                                                                                                                                           
       * as specified in the {@link #getThreadInfo(long[], boolean, boolean, int)}                                                                                                                                                                                                                                                                                            
       * method.                                                                                                                                                                                                                                                                                                                                                              
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @implSpec The default implementation throws                                                                                                                                                                                                                                                                                                                          
       * <tt>UnsupportedOperationException</tt>.                                                                                                                                                                                                                                                                                                                              
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @param  lockedMonitors if <tt>true</tt>, dump all locked monitors.                                                                                                                                                                                                                                                                                                   
       * @param  lockedSynchronizers if <tt>true</tt>, dump all locked                                                                                                                                                                                                                                                                                                        
       *             ownable synchronizers.                                                                                                                                                                                                                                                                                                                                   
       * @param  maxDepth indicates the maximum number of                                                                                                                                                                                                                                                                                                                     
       * {@link StackTraceElement} to be retrieved from the stack trace.                                                                                                                                                                                                                                                                                                      
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @return an array of {@link ThreadInfo} for all live threads.                                                                                                                                                                                                                                                                                                         
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @throws IllegalArgumentException if <tt>maxDepth</tt> is negative.                                                                                                                                                                                                                                                                                                   
       * @throws java.lang.SecurityException if a security manager                                                                                                                                                                                                                                                                                                            
       *         exists and the caller does not have                                                                                                                                                                                                                                                                                                                          
       *         ManagementPermission("monitor").                                                                                                                                                                                                                                                                                                                             
       * @throws java.lang.UnsupportedOperationException                                                                                                                                                                                                                                                                                                                      
       *         <ul>                                                                                                                                                                                                                                                                                                                                                         
       *           <li>if <tt>lockedMonitors</tt> is <tt>true</tt> but                                                                                                                                                                                                                                                                                                        
       *               the Java virtual machine does not support monitoring                                                                                                                                                                                                                                                                                                   
       *               of {@linkplain #isObjectMonitorUsageSupported                                                                                                                                                                                                                                                                                                          
       *               object monitor usage}; or</li>                                                                                                                                                                                                                                                                                                                         
       *           <li>if <tt>lockedSynchronizers</tt> is <tt>true</tt> but                                                                                                                                                                                                                                                                                                   
       *               the Java virtual machine does not support monitoring                                                                                                                                                                                                                                                                                                   
       *               of {@linkplain #isSynchronizerUsageSupported                                                                                                                                                                                                                                                                                                           
       *               ownable synchronizer usage}.</li>                                                                                                                                                                                                                                                                                                                      
       *         </ul>                                                                                                                                                                                                                                                                                                                                                        
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @see #isObjectMonitorUsageSupported                                                                                                                                                                                                                                                                                                                                  
       * @see #isSynchronizerUsageSupported                                                                                                                                                                                                                                                                                                                                   
       *                                                                                                                                                                                                                                                                                                                                                                      
       * @since 8u282                                                                                                                                                                                                                                                                                                                                                         
       */
      public default ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
                                                 boolean lockedSynchronizers, int maxDepth) {
          throw new UnsupportedOperationException();
      }

            phh Paul Hohensee
            phh Paul Hohensee
            Volker Simonis
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: