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

[REDO] JDK-8207266 ThreadMXBean::getThreadAllocatedBytes() can be quicker for self thread

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 11.0.9-oracle
    • core-svc
    • None
    • behavioral
    • minimal
    • Hide
      Adds a default interface method with well-understood semantics and leaves existing method semantics unchanged. Existing programs will continue to compile and execute as before.

      Note that c.s.m.ThreadMXBean extends j.l.m.ThreadMXBean, which in turn extends PlatformManagedObject. The Java 11 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. In fact, the nsk ThreadMXBean monitoring tests do, hence getCurrentThreadAllocatedBytes must have a default implementation. As does j.l.m.ThreadMXBean.getThreadInfo​(long[], boolean, boolean, int), it throws UnsupportedOperationException.


      Show
      Adds a default interface method with well-understood semantics and leaves existing method semantics unchanged. Existing programs will continue to compile and execute as before. Note that c.s.m.ThreadMXBean extends j.l.m.ThreadMXBean, which in turn extends PlatformManagedObject. The Java 11 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. In fact, the nsk ThreadMXBean monitoring tests do, hence getCurrentThreadAllocatedBytes must have a default implementation. As does j.l.m.ThreadMXBean.getThreadInfo​(long[], boolean, boolean, int), it throws UnsupportedOperationException.
    • Java API
    • JDK

      Original CSR: https://bugs.openjdk.java.net/browse/JDK-8231374

      There is a pair of original CSRs that need to be backported together:

      For CSR 1 the backport is this CSR.

      For CSR 2 the backport is https://bugs.openjdk.java.net/browse/JDK-8249103.

      The only differences from the original CSR are:

      1. Version tag for new method getCurrentThreadAllocatedBytes() was changed from @since 14 to @since 11.0.9
      2. Comment for JMM_VERSION_3 was changed from "JDK 14" to "JDK 11.0.9 and JDK 14" (please note that changes for JMM version were not included in the original CSR but were included in the change that was pushed in the main repository).

      Summary

      Add com.sun.management.ThreadMXBean::getCurrentThreadAllocatedBytes.

      Problem

      com.sun.management.ThreadMXBean includes getThreadAllocatedBytes in two versions, one which takes a thread_id and another which takes an array of thread_ids.

      getThreadAllocatedBytes(long id);
      getThreadAllocatedBytes(long[] ids);</code></pre>
      
      <p>It also includes versions of getThreadCpuTime and getThreadUserTime that take an array of thread_ids.</p>
      
      <pre class="prettyprint" ><code>getThreadCpuTime(long[] ids);
      getThreadUserTime(long[] ids);

      java.lang.thread.ThreadMXBean defines single thread_id and current thread versions of these.

      getThreadCpuTime(long id);
      getThreadUserTime(long id);
      getCurrentThreadCpuTime();
      getCurrentThreadUserTime();

      Three versions of Cpu and User time are thus available from com.sun.management.ThreadMXBean: current thread, single thread_id, and an array of thread_ids. Only two versions of AllocatedBytes are currently available: single thread_id and an array of thread_ids.

      The current thread versions of Cpu and User time are optimized to by avoiding checks needed by the versions that take thread_id(s). getCurrentThreadAllocatedBytes can also be so optimized, is useful for applications that monitor themselves, and rounds out the set of AllocatedBytes methods. As with the other AllocatedBytes methods, getCurrentThreadAllocatedBytes is a method on com.sun.management.ThreadMXBean rather than java.lang.thread.ThreadMXBean in order to avoid requiring all implementations to support it.

      Note also 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. In fact, the nsk ThreadMXBean monitoring tests do, hence getCurrentThreadAllocatedBytes must have a default implementation. Per its definition, that implementation is to throw an UnsupportedOperationException.

      Solution

      Add com.sun.management.ThreadMXBean::getCurrentThreadAllocatedBytes and increase JMM version.

      Specification

      /**
       * Returns an approximation of the total amount of memory, in bytes,
       * allocated in heap memory for the current thread.
       * The returned value is an approximation because some Java virtual machine
       * implementations may use object allocation mechanisms that result in a
       * delay between the time an object is allocated and the time its size is
       * recorded.
       *
       * <p>
       * This is a convenience method for local management use and is
       * equivalent to calling:
       * <blockquote><pre>
       *   {@link #getThreadAllocatedBytes getThreadAllocatedBytes}(Thread.currentThread().getId());
       * </pre></blockquote>
       *
       * @implSpec The default implementation throws
       * {@code UnsupportedOperationException}.
       *
       * @return an approximation of the total memory allocated, in bytes, in
       * heap memory for the current thread
       * if thread memory allocation measurement is enabled;
       * {@code -1} otherwise.
       *
       * @throws java.lang.UnsupportedOperationException if the Java virtual
       *         machine implementation does not support thread memory allocation
       *         measurement.
       *
       * @see #isThreadAllocatedMemorySupported
       * @see #isThreadAllocatedMemoryEnabled
       * @see #setThreadAllocatedMemoryEnabled
       */
      public default long getCurrentThreadAllocatedBytes() {
          throw new UnsupportedOperationException();
      }
      enum {
        JMM_VERSION_1   = 0x20010000,
        JMM_VERSION_1_0 = 0x20010000,
        JMM_VERSION_1_1 = 0x20010100, // JDK 6
        JMM_VERSION_1_2 = 0x20010200, // JDK 7
        JMM_VERSION_1_2_1 = 0x20010201, // JDK 7 GA
        JMM_VERSION_1_2_2 = 0x20010202,
        JMM_VERSION_2   = 0x20020000, // JDK 10
        JMM_VERSION_3   = 0x20030000, // JDK 11.0.9 and JDK 14
        JMM_VERSION     = JMM_VERSION_3
      };

            dtitov Daniil Titov (Inactive)
            phh Paul Hohensee
            Alex Menkov, Chris Plummer, Joe Darcy
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: