sun.nio.ch.DirectBuffer and jdk9/jigsaw
uschindler at apache.org
Thu Feb 23 16:54:07 UTC 2017
Why do you need the address at all in the Java code? Java code can use the official ByteBuffer methods to access the memory you are wrapping. In Java 9 that’s optimized very good by Hotspot and should be almost as fast as array accesses (we proved that in Apache Lucene - congrats to the Hotspot committers). If you need special access modes like volatile access, then you can use Java 9's VarHandles. You can get a VarHandle to the backing direct buffer using the MethodHandles API.
uschindler at apache.org
ASF Member, Apache Lucene PMC / Committer
> -----Original Message-----
> From: jigsaw-dev [mailto:jigsaw-dev-bounces at openjdk.java.net] On Behalf
> Of Vitaly Davidovich
> Sent: Thursday, February 23, 2017 5:30 PM
> To: Chris Hegarty <chris.hegarty at oracle.com>
> Cc: jigsaw-dev <jigsaw-dev at openjdk.java.net>
> Subject: Re: sun.nio.ch.DirectBuffer and jdk9/jigsaw
> On Thu, Feb 23, 2017 at 11:10 AM, Chris Hegarty
> <chris.hegarty at oracle.com>
> > > On 23 Feb 2017, at 11:30, Vitaly Davidovich <vitalyd at gmail.com> wrote:
> > >> ...
> > > The buffers are reused by having them point to different native memory
> > > block addresses; those blocks are managed by native code. As
> > > the ByteBuffer (DirectByteBuffer concretely) is used as the Java level
> > > interface/view of native memory, allowing Java and native code to
> > > communicate.
> > So a DBB, under your code, may report a different address at some time
> > in the future, to that of what it currently reports?
> > I was not aware of this
> > usecase. Is any similar code available on the web, or elsewhere, so we
> > could try to determine why this is being done?
> Unfortunately it's not open source code, and I don't immediately know of
> anything similar on the web (or otherwise). However, the gist is the
> 1) Allocate a 0-size DBB (i.e. ByteBuffer.allocateDirect(0)). This gives
> you a Java "handle", if you will, to some native memory. But, since this
> DBB will be attached/reattached to different memory dynamically, there's no
> need for an actual allocation.
> 2) Native code wants to expose a segment of memory to Java. In JNI, it
> sets the address and capacity of this DBB to the pointer where the native
> memory segment starts, and to the capacity (it knows how big the native
> segment is). Java code asks for this DBB to be "attached" to, say, some
> sort of message, and the JNI/native code perform these functions.
> 3) Java gets the attached DBB back, and can then use its API
> (getXXX/setXXX) to read/write that native block. Once the operation
> completes, the DBB is recycled for reuse (i.e. can be attached to a
> different native segment again).
> Obviously, we can use
> to get the address and then expose that via a JNI helper - in fact, that's
> what was done before. But, there's a JNI call penalty here for what is
> otherwise a memory read. DirectBuffer::address() solves that nicely, and
> also plays well with the C2 JIT (as mentioned) because the callsites where
> this is used only see DBB, and then the whole invokeinterface call is
> devirtualized and inlined into a quick type check and Java field read - the
> performance of this is, as you can imagine, significantly better than the
> JNI approach.
> If you think of what a DBB really is, it's pretty much what it's name
> suggests - it's an API to read/write to native memory, rather than Java
> heap memory (i.e. HeapByteBuffer). But, there's no reason the native
> memory backing the DBB has to also be allocated via Unsafe itself, although
> that's the more common scenario.
> On the Java side, consumers of this have a common and conventional API
> a byte buffer, i.e. ByteBuffer, which can optionally be used in the manner
> above (obviously callers will need to know what mode they're using).
> > -Chris.
More information about the jigsaw-dev