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 */
|