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

(jni) GetDirectBufferAddress performance problem

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P2 P2
    • 1.4.0
    • 1.4.0
    • hotspot
    • None
    • beta3
    • generic
    • generic

      From: Mark Reinhold <###@###.###>
      Date: Sun, 26 Aug 2001 15:02:07 -0700

      > From: Brian Doherty <###@###.###>
      > Date: Thu, 23 Aug 2001 18:08:37 -0500

      > I just instrumented the vm to track calls to GetDirectBufferAddress.
      >
      > Here is what I discovered:
      >
      > Total Time(ms) GDBA Calls GDBA Time(ms)
      > .5k 1189 200000 1785 (892)
      > 1k 1258 200000 1770 (885)
      > 2k 1552 200000 1765 (882)
      > 4k 2236 200000 1913 (956)
      > 8k 3273 200000 1742 (871)
      > 16k 5586 200000 1742 (871)
      > 32k 10183 200000 1730 (865)
      > 64k 19431 200000 1764 (882)
      >
      >
      > The number of calls to GetDirectBufferAddr are identical,
      > independent of the buffer size. This is due to the loop
      > going to 100000. There are two loops, one to warm up the
      > vm and the timed loop. So the number in parens in the
      > GDBA Time column is the one we are interested in. It is
      > nearly the entire difference between the native c
      > performance and the direct buffer beformance. (ignoring
      > the instrumentation overhead)
      >
      > I moved the boundaries of the instrumentation to include
      > only a single call within GetDirectBufferAddr and found
      > that of the ~850ms, nearly the entire amount is due to the
      > following line of code:
      >
      > return (void*) env->CallLongMethod(buf,directBufferAddress);
      >
      > I haven't had a chance to look into this method implementation
      > yet.

      > From: ###@###.###
      > Date: Fri, 24 Aug 2001 08:39:08 -0500

      > :^( -- The method address() called by CallLongMethod()
      > is a (read: the only) method on an interface called
      > sun.nio.ch.DirectBuffer. All implementations of this
      > method are protected and return the value of a protected
      > long address field.
      >
      > The DirectByteBuffer class implements this interface. However,
      > there are bunch of classes that implement this interface as well.
      > (DirectCharBuffer*, DirectLongBuffer*, ...).
      >
      > It's tempting to change the interface to have the field,
      > but then the field needs to be public instead of protected
      > and could then be easily modified/corrupted.
      >
      > So, there seems to be a good reason for this implementation
      > and it's beyond my my present understanding of nio and hotspot
      > on how this could be improved.

      It looks like what's going on here is that every call to GetDirectBufferAddress
      is paying for a virtual method invocation of DirectBuffer.address(). This is
      pretty expensive since it's an upcall from JNI to Java.

      We can pretty easily change things around so that GetDirectBufferAddress simply
      reads a field instead of having to run Java code. We'd do this by defining a
      common superclass of all direct-buffer classes that would serve to hold the
      address field. This way the implementation of GetDirectBufferAddress could
      cache the field ID at its first invocation and after that be very fast.

            kbr Kenneth Russell (Inactive)
            mr Mark Reinhold
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: