< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java

Print this page
rev 60127 : 8249205: Remove unnecessary trademark symbols


  39  * ranging from {@code 0} to {@code 9}, we can use the following code:
  40  *
  41  * <pre>{@code
  42 static final VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
  43 
  44 try (MemorySegment segment = MemorySegment.allocateNative(10 * 4)) {
  45     MemoryAddress base = segment.baseAddress();
  46     for (long i = 0 ; i < 10 ; i++) {
  47        intHandle.set(base.addOffset(i * 4), (int)i);
  48     }
  49 }
  50  * }</pre>
  51  *
  52  * Here we create a var handle, namely {@code intHandle}, to manipulate values of the primitive type {@code int}, at
  53  * a given memory location. Also, {@code intHandle} is stored in a {@code static} and {@code final} field, to achieve
  54  * better performance and allow for inlining of the memory access operation through the {@link java.lang.invoke.VarHandle}
  55  * instance. We then create a <em>native</em> memory segment, that is, a memory segment backed by
  56  * off-heap memory; the size of the segment is 40 bytes, enough to store 10 values of the primitive type {@code int}.
  57  * The segment is created inside a <em>try-with-resources</em> construct: this idiom ensures that all the memory resources
  58  * associated with the segment will be released at the end of the block, according to the semantics described in
  59  * Section {@jls 14.20.3} of <cite>The Java&trade; Language Specification</cite>. Inside the try-with-resources block, we initialize
  60  * the contents of the memory segment; more specifically, if we view the memory segment as a set of 10 adjacent slots,
  61  * {@code s[i]}, where {@code 0 <= i < 10}, where the size of each slot is exactly 4 bytes, the initialization logic above will set each slot
  62  * so that {@code s[i] = i}, again where {@code 0 <= i < 10}.
  63  *
  64  * <h2><a id="deallocation"></a>Deterministic deallocation</h2>
  65  *
  66  * When writing code that manipulates memory segments, especially if backed by memory which resides outside the Java heap, it is
  67  * crucial that the resources associated with a memory segment are released when the segment is no longer in use, by calling the {@link jdk.incubator.foreign.MemorySegment#close()}
  68  * method either explicitly, or implicitly, by relying on try-with-resources construct (as demonstrated in the example above).
  69  * Closing a given memory segment is an <em>atomic</em> operation which can either succeed - and result in the underlying
  70  * memory associated with the segment to be released, or <em>fail</em> with an exception.
  71  * <p>
  72  * The deterministic deallocation model differs significantly from the implicit strategies adopted within other APIs, most
  73  * notably the {@link java.nio.ByteBuffer} API: in that case, when a native byte buffer is created (see {@link java.nio.ByteBuffer#allocateDirect(int)}),
  74  * the underlying memory is not released until the byte buffer reference becomes <em>unreachable</em>. While implicit deallocation
  75  * models such as this can be very convenient - clients do not have to remember to <em>close</em> a direct buffer - such models can also make it
  76  * hard for clients to ensure that the memory associated with a direct buffer has indeed been released.
  77  *
  78  * <h2><a id="safety"></a>Safety</h2>
  79  *
  80  * This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment using
  81  * a memory address, such an address is validated (upon access), to make sure that it does not point to a memory location
  82  * which resides <em>outside</em> the boundaries of the memory segment it refers to. We call this guarantee <em>spatial safety</em>;
  83  * in other words, access to memory segments is bounds-checked, in the same way as array access is, as described in
  84  * Section {@jls 15.10.4} of <cite>The Java&trade; Language Specification</cite>.
  85  * <p>
  86  * Since memory segments can be closed (see above), a memory address is also validated (upon access) to make sure that
  87  * the segment it belongs to has not been closed prematurely. We call this guarantee <em>temporal safety</em>. Note that,
  88  * in the general case, guaranteeing temporal safety can be hard, as multiple threads could attempt to access and/or close
  89  * the same memory segment concurrently. The memory access API addresses this problem by imposing strong
  90  * <a href="MemorySegment.html#thread-confinement"><em>thread-confinement</em></a> guarantees on memory segments: each
  91  * memory segment is associated with an owner thread, which is the only thread that can either access or close the segment.
  92  * <p>
  93  * Together, spatial and temporal safety ensure that each memory access operation either succeeds - and accesses a valid
  94  * memory location - or fails.
  95  */
  96 package jdk.incubator.foreign;


  39  * ranging from {@code 0} to {@code 9}, we can use the following code:
  40  *
  41  * <pre>{@code
  42 static final VarHandle intHandle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
  43 
  44 try (MemorySegment segment = MemorySegment.allocateNative(10 * 4)) {
  45     MemoryAddress base = segment.baseAddress();
  46     for (long i = 0 ; i < 10 ; i++) {
  47        intHandle.set(base.addOffset(i * 4), (int)i);
  48     }
  49 }
  50  * }</pre>
  51  *
  52  * Here we create a var handle, namely {@code intHandle}, to manipulate values of the primitive type {@code int}, at
  53  * a given memory location. Also, {@code intHandle} is stored in a {@code static} and {@code final} field, to achieve
  54  * better performance and allow for inlining of the memory access operation through the {@link java.lang.invoke.VarHandle}
  55  * instance. We then create a <em>native</em> memory segment, that is, a memory segment backed by
  56  * off-heap memory; the size of the segment is 40 bytes, enough to store 10 values of the primitive type {@code int}.
  57  * The segment is created inside a <em>try-with-resources</em> construct: this idiom ensures that all the memory resources
  58  * associated with the segment will be released at the end of the block, according to the semantics described in
  59  * Section {@jls 14.20.3} of <cite>The Java Language Specification</cite>. Inside the try-with-resources block, we initialize
  60  * the contents of the memory segment; more specifically, if we view the memory segment as a set of 10 adjacent slots,
  61  * {@code s[i]}, where {@code 0 <= i < 10}, where the size of each slot is exactly 4 bytes, the initialization logic above will set each slot
  62  * so that {@code s[i] = i}, again where {@code 0 <= i < 10}.
  63  *
  64  * <h2><a id="deallocation"></a>Deterministic deallocation</h2>
  65  *
  66  * When writing code that manipulates memory segments, especially if backed by memory which resides outside the Java heap, it is
  67  * crucial that the resources associated with a memory segment are released when the segment is no longer in use, by calling the {@link jdk.incubator.foreign.MemorySegment#close()}
  68  * method either explicitly, or implicitly, by relying on try-with-resources construct (as demonstrated in the example above).
  69  * Closing a given memory segment is an <em>atomic</em> operation which can either succeed - and result in the underlying
  70  * memory associated with the segment to be released, or <em>fail</em> with an exception.
  71  * <p>
  72  * The deterministic deallocation model differs significantly from the implicit strategies adopted within other APIs, most
  73  * notably the {@link java.nio.ByteBuffer} API: in that case, when a native byte buffer is created (see {@link java.nio.ByteBuffer#allocateDirect(int)}),
  74  * the underlying memory is not released until the byte buffer reference becomes <em>unreachable</em>. While implicit deallocation
  75  * models such as this can be very convenient - clients do not have to remember to <em>close</em> a direct buffer - such models can also make it
  76  * hard for clients to ensure that the memory associated with a direct buffer has indeed been released.
  77  *
  78  * <h2><a id="safety"></a>Safety</h2>
  79  *
  80  * This API provides strong safety guarantees when it comes to memory access. First, when dereferencing a memory segment using
  81  * a memory address, such an address is validated (upon access), to make sure that it does not point to a memory location
  82  * which resides <em>outside</em> the boundaries of the memory segment it refers to. We call this guarantee <em>spatial safety</em>;
  83  * in other words, access to memory segments is bounds-checked, in the same way as array access is, as described in
  84  * Section {@jls 15.10.4} of <cite>The Java Language Specification</cite>.
  85  * <p>
  86  * Since memory segments can be closed (see above), a memory address is also validated (upon access) to make sure that
  87  * the segment it belongs to has not been closed prematurely. We call this guarantee <em>temporal safety</em>. Note that,
  88  * in the general case, guaranteeing temporal safety can be hard, as multiple threads could attempt to access and/or close
  89  * the same memory segment concurrently. The memory access API addresses this problem by imposing strong
  90  * <a href="MemorySegment.html#thread-confinement"><em>thread-confinement</em></a> guarantees on memory segments: each
  91  * memory segment is associated with an owner thread, which is the only thread that can either access or close the segment.
  92  * <p>
  93  * Together, spatial and temporal safety ensure that each memory access operation either succeeds - and accesses a valid
  94  * memory location - or fails.
  95  */
  96 package jdk.incubator.foreign;
< prev index next >