Hi,

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.

Uwe

-----
Uwe Schindler
[email protected] 
ASF Member, Apache Lucene PMC / Committer
Bremen, Germany
http://lucene.apache.org/

> -----Original Message-----
> From: jigsaw-dev [mailto:[email protected]] On Behalf
> Of Vitaly Davidovich
> Sent: Thursday, February 23, 2017 5:30 PM
> To: Chris Hegarty <[email protected]>
> Cc: jigsaw-dev <[email protected]>
> Subject: Re: sun.nio.ch.DirectBuffer and jdk9/jigsaw
> 
> On Thu, Feb 23, 2017 at 11:10 AM, Chris Hegarty
> <[email protected]>
> wrote:
> 
> >
> > > On 23 Feb 2017, at 11:30, Vitaly Davidovich <[email protected]> wrote:
> > >> ...
> > > The buffers are reused by having them point to different native memory
> > > block addresses; those blocks are managed by native code.  As
> mentioned,
> > > 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?
> 
> Correct.
> 
> > 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
> following:
> 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
> http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.
> html#GetDirectBufferAddress
> 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
> over
> 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.
> >
> >

Reply via email to