< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java

Print this page
M MemorySegment.java


 160  * Implementations of this interface are immutable and thread-safe.
 161  */
 162 public interface MemorySegment extends AutoCloseable {
 163 
 164     /**
 165      * The base memory address associated with this memory segment. The returned address is
 166      * a <em>checked</em> memory address and can therefore be used in derefrence operations
 167      * (see {@link MemoryAddress}).
 168      * @return The base memory address.
 169      */
 170     MemoryAddress baseAddress();
 171 
 172     /**
 173      * Returns a spliterator for the given memory segment. The returned spliterator reports {@link Spliterator#SIZED},
 174      * {@link Spliterator#SUBSIZED}, {@link Spliterator#IMMUTABLE}, {@link Spliterator#NONNULL} and {@link Spliterator#ORDERED}
 175      * characteristics.
 176      * <p>
 177      * The returned spliterator splits the segment according to the specified sequence layout; that is,
 178      * if the supplied layout is a sequence layout whose element count is {@code N}, then calling {@link Spliterator#trySplit()}
 179      * will result in a spliterator serving approximatively {@code N/2} elements (depending on whether N is even or not).
 180      * As such, splitting is possible as long as {@code N >= 2}.

 181      * <p>
 182      * The returned spliterator effectively allows to slice a segment into disjoint sub-segments, which can then
 183      * be processed in parallel by multiple threads (if the access mode {@link #ACQUIRE} is set).
 184      * While closing the segment (see {@link #close()}) during pending concurrent execution will generally
 185      * fail with an exception, it is possible to close a segment when a spliterator has been obtained but no thread
 186      * is actively working on it using {@link Spliterator#tryAdvance(Consumer)}; in such cases, any subsequent call
 187      * to {@link Spliterator#tryAdvance(Consumer)} will fail with an exception.
 188      * @param segment the segment to be used for splitting.
 189      * @param layout the layout to be used for splitting.
 190      * @param <S> the memory segment type
 191      * @return the element spliterator for this segment
 192      * @throws IllegalStateException if the segment is not <em>alive</em>, or if access occurs from a thread other than the
 193      * thread owning this segment
 194      */
 195     static <S extends MemorySegment> Spliterator<S> spliterator(S segment, SequenceLayout layout) {
 196         return AbstractMemorySegmentImpl.spliterator(segment, layout);
 197     }
 198 
 199     /**
 200      * The thread owning this segment.


 303      * e.g. because it models an heap-based segment that is not based on a {@code byte[]}), or if its size is greater
 304      * than {@link Integer#MAX_VALUE}, or if the segment does not support the {@link #READ} access mode.
 305      */
 306     ByteBuffer asByteBuffer();
 307 
 308     /**
 309      * Copy the contents of this memory segment into a fresh byte array.
 310      * @return a fresh byte array copy of this memory segment.
 311      * @throws UnsupportedOperationException if this segment's contents cannot be copied into a {@link byte[]} instance,
 312      * e.g. its size is greater than {@link Integer#MAX_VALUE}.
 313      * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the
 314      * thread owning this segment.
 315      */
 316     byte[] toByteArray();
 317 
 318     /**
 319      * Creates a new buffer memory segment that models the memory associated with the given byte
 320      * buffer. The segment starts relative to the buffer's position (inclusive)
 321      * and ends relative to the buffer's limit (exclusive).
 322      * <p>




 323      * The resulting memory segment keeps a reference to the backing buffer, to ensure it remains <em>reachable</em>
 324      * for the life-time of the segment.
 325      *
 326      * @param bb the byte buffer backing the buffer memory segment.
 327      * @return a new buffer memory segment.
 328      */
 329     static MemorySegment ofByteBuffer(ByteBuffer bb) {
 330         return AbstractMemorySegmentImpl.ofBuffer(bb);
 331     }
 332 
 333     /**
 334      * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
 335      * <p>
 336      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 337      * for the life-time of the segment.
 338      *
 339      * @param arr the primitive array backing the array memory segment.
 340      * @return a new array memory segment.
 341      */
 342     static MemorySegment ofArray(byte[] arr) {
 343         return HeapMemorySegmentImpl.makeArraySegment(arr);
 344     }
 345 
 346     /**
 347      * Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
 348      * <p>
 349      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 350      * for the life-time of the segment.
 351      *
 352      * @param arr the primitive array backing the array memory segment.
 353      * @return a new array memory segment.
 354      */
 355     static MemorySegment ofArray(char[] arr) {
 356         return HeapMemorySegmentImpl.makeArraySegment(arr);
 357     }
 358 
 359     /**
 360      * Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
 361      * <p>
 362      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 363      * for the life-time of the segment.
 364      *
 365      * @param arr the primitive array backing the array memory segment.
 366      * @return a new array memory segment.
 367      */
 368     static MemorySegment ofArray(short[] arr) {
 369         return HeapMemorySegmentImpl.makeArraySegment(arr);
 370     }
 371 
 372     /**
 373      * Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
 374      * <p>
 375      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 376      * for the life-time of the segment.
 377      *
 378      * @param arr the primitive array backing the array memory segment.
 379      * @return a new array memory segment.
 380      */
 381     static MemorySegment ofArray(int[] arr) {
 382         return HeapMemorySegmentImpl.makeArraySegment(arr);
 383     }
 384 
 385     /**
 386      * Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
 387      * <p>
 388      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 389      * for the life-time of the segment.
 390      *
 391      * @param arr the primitive array backing the array memory segment.
 392      * @return a new array memory segment.
 393      */
 394     static MemorySegment ofArray(float[] arr) {
 395         return HeapMemorySegmentImpl.makeArraySegment(arr);
 396     }
 397 
 398     /**
 399      * Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
 400      * <p>
 401      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 402      * for the life-time of the segment.
 403      *
 404      * @param arr the primitive array backing the array memory segment.
 405      * @return a new array memory segment.
 406      */
 407     static MemorySegment ofArray(long[] arr) {
 408         return HeapMemorySegmentImpl.makeArraySegment(arr);
 409     }
 410 
 411     /**
 412      * Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
 413      * <p>
 414      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 415      * for the life-time of the segment.
 416      *
 417      * @param arr the primitive array backing the array memory segment.
 418      * @return a new array memory segment.
 419      */
 420     static MemorySegment ofArray(double[] arr) {
 421         return HeapMemorySegmentImpl.makeArraySegment(arr);
 422     }
 423 
 424     /**
 425      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout.
 426      * <p>
 427      * This is equivalent to the following code:
 428      * <blockquote><pre>{@code
 429     allocateNative(layout.bytesSize(), layout.bytesAlignment());
 430      * }</pre></blockquote>
 431      *
 432      * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 433      * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment,
 434      * to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
 435      *


 446      * <p>
 447      * This is equivalent to the following code:
 448      * <blockquote><pre>{@code
 449 allocateNative(bytesSize, 1);
 450      * }</pre></blockquote>
 451      *
 452      * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 453      * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment,
 454      * to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
 455      *
 456      * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment.
 457      * @return a new native memory segment.
 458      * @throws IllegalArgumentException if {@code bytesSize < 0}.
 459      */
 460     static MemorySegment allocateNative(long bytesSize) {
 461         return allocateNative(bytesSize, 1);
 462     }
 463 
 464     /**
 465      * Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.




 466      *
 467      * @implNote When obtaining a mapped segment from a newly created file, the initialization state of the contents of the block
 468      * of mapped memory associated with the returned mapped memory segment is unspecified and should not be relied upon.
 469      *
 470      * @param path the path to the file to memory map.
 471      * @param bytesSize the size (in bytes) of the mapped memory backing the memory segment.
 472      * @param mapMode a file mapping mode, see {@link FileChannel#map(FileChannel.MapMode, long, long)}; the chosen mapping mode
 473      *                might affect the behavior of the returned memory mapped segment (see {@link MappedMemorySegment#force()}).
 474      * @return a new mapped memory segment.
 475      * @throws IllegalArgumentException if {@code bytesSize < 0}.
 476      * @throws UnsupportedOperationException if an unsupported map mode is specified.
 477      * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs.
 478      */
 479     static MappedMemorySegment mapFromPath(Path path, long bytesSize, FileChannel.MapMode mapMode) throws IOException {
 480         return MappedMemorySegmentImpl.makeMappedSegment(path, bytesSize, mapMode);
 481     }
 482 
 483     /**
 484      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and
 485      * alignment constraint (in bytes).
 486      *
 487      * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 488      * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment,
 489      * to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
 490      *
 491      * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment.
 492      * @param alignmentBytes the alignment constraint (in bytes) of the off-heap memory block backing the native memory segment.
 493      * @return a new native memory segment.
 494      * @throws IllegalArgumentException if {@code bytesSize < 0}, {@code alignmentBytes < 0}, or if {@code alignmentBytes}
 495      * is not a power of 2.
 496      */
 497     static MemorySegment allocateNative(long bytesSize, long alignmentBytes) {
 498         if (bytesSize <= 0) {
 499             throw new IllegalArgumentException("Invalid allocation size : " + bytesSize);
 500         }
 501 
 502         if (alignmentBytes < 0 ||
 503                 ((alignmentBytes & (alignmentBytes - 1)) != 0L)) {
 504             throw new IllegalArgumentException("Invalid alignment constraint : " + alignmentBytes);
 505         }
 506 
 507         return NativeMemorySegmentImpl.makeNativeSegment(bytesSize, alignmentBytes);
 508     }
 509 
 510     /**
 511      * Returns a new native memory segment with given base address and size; the returned segment has its own temporal
 512      * bounds, and can therefore be closed; closing such a segment can optionally result in calling an user-provided cleanup
 513      * action. This method can be very useful when interacting with custom native memory sources (e.g. custom allocators,
 514      * GPU memory, etc.), where an address to some underlying memory region is typically obtained from native code
 515      * (often as a plain {@code long} value).
 516      * <p>
 517      * This method is <em>restricted</em>. Restricted method are unsafe, and, if used incorrectly, their use might crash
 518      * the JVM crash or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
 519      * restricted methods, and use safe and supported functionalities, where possible.
 520      *
 521      * @param addr the desired base address
 522      * @param bytesSize the desired size.
 523      * @param owner the desired owner thread. If {@code owner == null}, the returned segment is <em>not</em> confined.
 524      * @param cleanup a cleanup action to be executed when the {@link MemorySegment#close()} method is called on the
 525      *                returned segment. If {@code cleanup == null}, no cleanup action is executed.
 526      * @param attachment an object that must be kept alive by the returned segment; this can be useful when
 527      *                   the returned segment depends on memory which could be released if a certain object
 528      *                   is determined to be unreacheable. In most cases this will be set to {@code null}.
 529      * @return a new native memory segment with given base address, size, owner, cleanup action and object attachment.
 530      * @throws IllegalArgumentException if {@code bytesSize <= 0}.
 531      * @throws UnsupportedOperationException if {@code addr} is associated with an heap segment.
 532      * @throws IllegalAccessError if the runtime property {@code foreign.restricted} is not set to either
 533      * {@code permit}, {@code warn} or {@code debug} (the default value is set to {@code deny}).
 534      * @throws NullPointerException if {@code addr == null}.
 535      */




 160  * Implementations of this interface are immutable and thread-safe.
 161  */
 162 public interface MemorySegment extends AutoCloseable {
 163 
 164     /**
 165      * The base memory address associated with this memory segment. The returned address is
 166      * a <em>checked</em> memory address and can therefore be used in derefrence operations
 167      * (see {@link MemoryAddress}).
 168      * @return The base memory address.
 169      */
 170     MemoryAddress baseAddress();
 171 
 172     /**
 173      * Returns a spliterator for the given memory segment. The returned spliterator reports {@link Spliterator#SIZED},
 174      * {@link Spliterator#SUBSIZED}, {@link Spliterator#IMMUTABLE}, {@link Spliterator#NONNULL} and {@link Spliterator#ORDERED}
 175      * characteristics.
 176      * <p>
 177      * The returned spliterator splits the segment according to the specified sequence layout; that is,
 178      * if the supplied layout is a sequence layout whose element count is {@code N}, then calling {@link Spliterator#trySplit()}
 179      * will result in a spliterator serving approximatively {@code N/2} elements (depending on whether N is even or not).
 180      * As such, splitting is possible as long as {@code N >= 2}. The spliterator returns segments that feature the same
 181      * <a href="#access-modes">access modes</a> as the given segment less the {@link #CLOSE} access mode.
 182      * <p>
 183      * The returned spliterator effectively allows to slice a segment into disjoint sub-segments, which can then
 184      * be processed in parallel by multiple threads (if the access mode {@link #ACQUIRE} is set).
 185      * While closing the segment (see {@link #close()}) during pending concurrent execution will generally
 186      * fail with an exception, it is possible to close a segment when a spliterator has been obtained but no thread
 187      * is actively working on it using {@link Spliterator#tryAdvance(Consumer)}; in such cases, any subsequent call
 188      * to {@link Spliterator#tryAdvance(Consumer)} will fail with an exception.
 189      * @param segment the segment to be used for splitting.
 190      * @param layout the layout to be used for splitting.
 191      * @param <S> the memory segment type
 192      * @return the element spliterator for this segment
 193      * @throws IllegalStateException if the segment is not <em>alive</em>, or if access occurs from a thread other than the
 194      * thread owning this segment
 195      */
 196     static <S extends MemorySegment> Spliterator<S> spliterator(S segment, SequenceLayout layout) {
 197         return AbstractMemorySegmentImpl.spliterator(segment, layout);
 198     }
 199 
 200     /**
 201      * The thread owning this segment.


 304      * e.g. because it models an heap-based segment that is not based on a {@code byte[]}), or if its size is greater
 305      * than {@link Integer#MAX_VALUE}, or if the segment does not support the {@link #READ} access mode.
 306      */
 307     ByteBuffer asByteBuffer();
 308 
 309     /**
 310      * Copy the contents of this memory segment into a fresh byte array.
 311      * @return a fresh byte array copy of this memory segment.
 312      * @throws UnsupportedOperationException if this segment's contents cannot be copied into a {@link byte[]} instance,
 313      * e.g. its size is greater than {@link Integer#MAX_VALUE}.
 314      * @throws IllegalStateException if this segment has been closed, or if access occurs from a thread other than the
 315      * thread owning this segment.
 316      */
 317     byte[] toByteArray();
 318 
 319     /**
 320      * Creates a new buffer memory segment that models the memory associated with the given byte
 321      * buffer. The segment starts relative to the buffer's position (inclusive)
 322      * and ends relative to the buffer's limit (exclusive).
 323      * <p>
 324      * The segment will feature all <a href="#access-modes">access modes</a>, unless the given
 325      * buffer is {@linkplain ByteBuffer#isReadOnly() read-only} in which case the segment will
 326      * not feature the {@link #WRITE} access mode.
 327      * <p>
 328      * The resulting memory segment keeps a reference to the backing buffer, to ensure it remains <em>reachable</em>
 329      * for the life-time of the segment.
 330      *
 331      * @param bb the byte buffer backing the buffer memory segment.
 332      * @return a new buffer memory segment.
 333      */
 334     static MemorySegment ofByteBuffer(ByteBuffer bb) {
 335         return AbstractMemorySegmentImpl.ofBuffer(bb);
 336     }
 337 
 338     /**
 339      * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array.
 340      * <p>
 341      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 342      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 343      *
 344      * @param arr the primitive array backing the array memory segment.
 345      * @return a new array memory segment.
 346      */
 347     static MemorySegment ofArray(byte[] arr) {
 348         return HeapMemorySegmentImpl.makeArraySegment(arr);
 349     }
 350 
 351     /**
 352      * Creates a new array memory segment that models the memory associated with a given heap-allocated char array.
 353      * <p>
 354      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 355      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 356      *
 357      * @param arr the primitive array backing the array memory segment.
 358      * @return a new array memory segment.
 359      */
 360     static MemorySegment ofArray(char[] arr) {
 361         return HeapMemorySegmentImpl.makeArraySegment(arr);
 362     }
 363 
 364     /**
 365      * Creates a new array memory segment that models the memory associated with a given heap-allocated short array.
 366      * <p>
 367      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 368      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 369      *
 370      * @param arr the primitive array backing the array memory segment.
 371      * @return a new array memory segment.
 372      */
 373     static MemorySegment ofArray(short[] arr) {
 374         return HeapMemorySegmentImpl.makeArraySegment(arr);
 375     }
 376 
 377     /**
 378      * Creates a new array memory segment that models the memory associated with a given heap-allocated int array.
 379      * <p>
 380      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 381      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 382      *
 383      * @param arr the primitive array backing the array memory segment.
 384      * @return a new array memory segment.
 385      */
 386     static MemorySegment ofArray(int[] arr) {
 387         return HeapMemorySegmentImpl.makeArraySegment(arr);
 388     }
 389 
 390     /**
 391      * Creates a new array memory segment that models the memory associated with a given heap-allocated float array.
 392      * <p>
 393      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 394      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 395      *
 396      * @param arr the primitive array backing the array memory segment.
 397      * @return a new array memory segment.
 398      */
 399     static MemorySegment ofArray(float[] arr) {
 400         return HeapMemorySegmentImpl.makeArraySegment(arr);
 401     }
 402 
 403     /**
 404      * Creates a new array memory segment that models the memory associated with a given heap-allocated long array.
 405      * <p>
 406      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 407      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 408      *
 409      * @param arr the primitive array backing the array memory segment.
 410      * @return a new array memory segment.
 411      */
 412     static MemorySegment ofArray(long[] arr) {
 413         return HeapMemorySegmentImpl.makeArraySegment(arr);
 414     }
 415 
 416     /**
 417      * Creates a new array memory segment that models the memory associated with a given heap-allocated double array.
 418      * <p>
 419      * The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
 420      * for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
 421      *
 422      * @param arr the primitive array backing the array memory segment.
 423      * @return a new array memory segment.
 424      */
 425     static MemorySegment ofArray(double[] arr) {
 426         return HeapMemorySegmentImpl.makeArraySegment(arr);
 427     }
 428 
 429     /**
 430      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given layout.
 431      * <p>
 432      * This is equivalent to the following code:
 433      * <blockquote><pre>{@code
 434     allocateNative(layout.bytesSize(), layout.bytesAlignment());
 435      * }</pre></blockquote>
 436      *
 437      * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 438      * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment,
 439      * to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
 440      *


 451      * <p>
 452      * This is equivalent to the following code:
 453      * <blockquote><pre>{@code
 454 allocateNative(bytesSize, 1);
 455      * }</pre></blockquote>
 456      *
 457      * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 458      * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment,
 459      * to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
 460      *
 461      * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment.
 462      * @return a new native memory segment.
 463      * @throws IllegalArgumentException if {@code bytesSize < 0}.
 464      */
 465     static MemorySegment allocateNative(long bytesSize) {
 466         return allocateNative(bytesSize, 1);
 467     }
 468 
 469     /**
 470      * Creates a new mapped memory segment that models a memory-mapped region of a file from a given path.
 471      * <p>
 472      * The segment will feature all <a href="#access-modes">access modes</a>, unless the given mapping mode
 473      * is {@linkplain FileChannel.MapMode#READ_ONLY READ_ONLY}, in which case the segment will not feature
 474      * the {@link #WRITE} access mode.
 475      *
 476      * @implNote When obtaining a mapped segment from a newly created file, the initialization state of the contents of the block
 477      * of mapped memory associated with the returned mapped memory segment is unspecified and should not be relied upon.
 478      *
 479      * @param path the path to the file to memory map.
 480      * @param bytesSize the size (in bytes) of the mapped memory backing the memory segment.
 481      * @param mapMode a file mapping mode, see {@link FileChannel#map(FileChannel.MapMode, long, long)}; the chosen mapping mode
 482      *                might affect the behavior of the returned memory mapped segment (see {@link MappedMemorySegment#force()}).
 483      * @return a new mapped memory segment.
 484      * @throws IllegalArgumentException if {@code bytesSize < 0}.
 485      * @throws UnsupportedOperationException if an unsupported map mode is specified.
 486      * @throws IOException if the specified path does not point to an existing file, or if some other I/O error occurs.
 487      */
 488     static MappedMemorySegment mapFromPath(Path path, long bytesSize, FileChannel.MapMode mapMode) throws IOException {
 489         return MappedMemorySegmentImpl.makeMappedSegment(path, bytesSize, mapMode);
 490     }
 491 
 492     /**
 493      * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and
 494      * alignment constraint (in bytes). The segment will feature all <a href="#access-modes">access modes</a>.
 495      *
 496      * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero.
 497      * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment,
 498      * to make sure the backing off-heap memory block is deallocated accordingly. Failure to do so will result in off-heap memory leaks.
 499      *
 500      * @param bytesSize the size (in bytes) of the off-heap memory block backing the native memory segment.
 501      * @param alignmentBytes the alignment constraint (in bytes) of the off-heap memory block backing the native memory segment.
 502      * @return a new native memory segment.
 503      * @throws IllegalArgumentException if {@code bytesSize < 0}, {@code alignmentBytes < 0}, or if {@code alignmentBytes}
 504      * is not a power of 2.
 505      */
 506     static MemorySegment allocateNative(long bytesSize, long alignmentBytes) {
 507         if (bytesSize <= 0) {
 508             throw new IllegalArgumentException("Invalid allocation size : " + bytesSize);
 509         }
 510 
 511         if (alignmentBytes < 0 ||
 512                 ((alignmentBytes & (alignmentBytes - 1)) != 0L)) {
 513             throw new IllegalArgumentException("Invalid alignment constraint : " + alignmentBytes);
 514         }
 515 
 516         return NativeMemorySegmentImpl.makeNativeSegment(bytesSize, alignmentBytes);
 517     }
 518 
 519     /**
 520      * Returns a new native memory segment with given base address and size; the returned segment has its own temporal
 521      * bounds, and can therefore be closed; closing such a segment can optionally result in calling an user-provided cleanup
 522      * action. This method can be very useful when interacting with custom native memory sources (e.g. custom allocators,
 523      * GPU memory, etc.), where an address to some underlying memory region is typically obtained from native code
 524      * (often as a plain {@code long} value). The segment will feature all <a href="#access-modes">access modes</a>.
 525      * <p>
 526      * This method is <em>restricted</em>. Restricted method are unsafe, and, if used incorrectly, their use might crash
 527      * the JVM crash or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
 528      * restricted methods, and use safe and supported functionalities, where possible.
 529      *
 530      * @param addr the desired base address
 531      * @param bytesSize the desired size.
 532      * @param owner the desired owner thread. If {@code owner == null}, the returned segment is <em>not</em> confined.
 533      * @param cleanup a cleanup action to be executed when the {@link MemorySegment#close()} method is called on the
 534      *                returned segment. If {@code cleanup == null}, no cleanup action is executed.
 535      * @param attachment an object that must be kept alive by the returned segment; this can be useful when
 536      *                   the returned segment depends on memory which could be released if a certain object
 537      *                   is determined to be unreacheable. In most cases this will be set to {@code null}.
 538      * @return a new native memory segment with given base address, size, owner, cleanup action and object attachment.
 539      * @throws IllegalArgumentException if {@code bytesSize <= 0}.
 540      * @throws UnsupportedOperationException if {@code addr} is associated with an heap segment.
 541      * @throws IllegalAccessError if the runtime property {@code foreign.restricted} is not set to either
 542      * {@code permit}, {@code warn} or {@code debug} (the default value is set to {@code deny}).
 543      * @throws NullPointerException if {@code addr == null}.
 544      */


< prev index next >