Spec-Zone.ru › OpenJDK 25

Интерфейс Arena

Все супер интерфейсы:
AutoCloseable, SegmentAllocator
public interface Arena extends SegmentAllocator, AutoCloseable
Арена управляет жизненным циклом сегментов нативной памяти, обеспечивая гибкое выделение памяти и своевременное освобождение.

У арены есть область действия — область действия арены. Все сегменты, выделенные ареной, связаны с областью действия арены. Таким образом, арена определяет временные границы всех выделенных ею сегментов памяти.

Кроме того, арена определяет, должен ли доступ к выделенным ею сегментам памяти быть ограничен определёнными потоками. Арена является SegmentAllocator и предоставляет несколько методов выделения памяти, которые клиенты могут использовать для получения нативных сегментов.

Простейшая арена — это глобальная арена. Глобальная арена имеет неограниченный срок жизни. Областью действия глобальной арены является глобальная область действия. Таким образом, нативные сегменты, выделенные с помощью глобальной арены, всегда доступны, а поддерживающие их области памяти никогда не освобождаются. Кроме того, сегменты памяти, выделенные с помощью глобальной арены, могут быть доступны из любого потока.

 MemorySegment segment = Arena.global().allocate(100, 1);
 ...
 // segment is never deallocated!

В качестве альтернативы клиенты могут получить автоматическую арену — арену с ограниченным сроком жизни, которым автоматически управляет сборщик мусора. Область действия автоматической арены является автоматической областью действия. Таким образом, области памяти, поддерживающие сегменты памяти, выделенные с помощью автоматической арены, освобождаются в неопределённый момент времени после того, как автоматическая арена (и все выделенные ею сегменты) становятся недостижимыми, как показано ниже:

 MemorySegment segment = Arena.ofAuto().allocate(100, 1);
 ...
 segment = null; // the segment region becomes available for deallocation after this point
Сегменты памяти, выделенные с помощью автоматической арены, также могут быть доступны из любого потока.

Вместо того чтобы оставлять освобождение памяти на усмотрение среды выполнения Java, клиенты часто хотят контролировать момент освобождения областей памяти, поддерживающих сегменты памяти. Это обеспечивают два типа арен: ограниченные и общие. Обе разновидности имеют ограниченный срок жизни, которым управляют вручную. Например, после успешного закрытия ограниченной арены её область действия становится недействительной. В результате доступ к выделенным ареной сегментам памяти становится невозможным, а области памяти освобождаются:

 MemorySegment segment = null;
 try (Arena arena = Arena.ofConfined()) {
     segment = arena.allocate(100);
     ...
 } // segment region deallocated here
 segment.get(ValueLayout.JAVA_BYTE, 0); // throws IllegalStateException
Доступ к сегментам памяти, выделенным с помощью ограниченной арены, может осуществлять (и закрывать их) только поток, создавший арену. Если требуется доступ к сегменту памяти из нескольких потоков, клиенты могут вместо этого выделять сегменты в общей арене.

Характеристики различных арен сведены в таблицу ниже:

Характеристики арен
Тип Ограниченный срок жизни Можно закрыть явно Доступна из нескольких потоков
Глобальная Нет Нет Да
Автоматическая Да Нет Да
Ограниченная Да Да Нет
Общая Да Да Да

Безопасность и привязка к потоку

Арены обеспечивают строгие гарантии временной безопасности: к сегменту памяти, выделенному ареной, нельзя получить доступ после закрытия арены. Стоимость обеспечения этой гарантии зависит от числа потоков, имеющих доступ к сегментам памяти, выделенным ареной. Например, если арену всегда создаёт и закрывает один и тот же поток и доступ к выделенным ею сегментам памяти всегда осуществляется из этого же потока, обеспечение корректности не представляет сложности.

Напротив, если арена выделяет сегменты, доступные из нескольких потоков, или если арену может закрыть поток, отличный от потока, осуществляющего доступ, обеспечить корректность гораздо сложнее. Например, сегмент, выделенный ареной, может использоваться в то время, как другой поток пытается одновременно закрыть арену. Чтобы обеспечить строгую гарантию временной безопасности и при этом не заставлять каждого клиента, даже самого простого, нести дополнительные затраты производительности, арены делятся на арены с привязкой к потоку и общие арены.

Ограниченные арены обеспечивают строгие гарантии привязки к потоку. При создании им назначается поток-владелец — обычно поток, инициировавший операцию создания. Доступ к сегментам, созданным ограниченной ареной, может осуществлять только поток-владелец. Кроме того, любая попытка закрыть ограниченную арену из потока, отличного от потока-владельца, завершится исключением WrongThreadException.

У общих арен, напротив, нет потока-владельца. Доступ к сегментам, созданным общей ареной, может осуществлять любой поток. Это может быть полезно, когда нескольким потокам нужно одновременно обращаться к одному и тому же сегменту памяти (например, при параллельной обработке). Кроме того, общую арену может закрыть любой поток.

Пользовательские арены

Клиенты могут определять пользовательские арены для реализации более эффективных стратегий выделения памяти или для более точного контроля над тем, когда (и кем) арена может быть закрыта. Например, следующий код определяет сегментирующую арену, которая ведёт себя как ограниченная арена (то есть поддерживает доступ из одного потока), но внутри использует сегментирующий распределитель для обработки запросов на выделение памяти. При закрытии сегментирующей арены закрывается и базовая ограниченная арена; это делает недействительными все сегменты, выделенные сегментирующей ареной (поскольку её область действия совпадает с областью действия базовой ограниченной арены):
class SlicingArena implements Arena {
    final Arena arena = Arena.ofConfined();
    final SegmentAllocator slicingAllocator;

    SlicingArena(long size) {
        slicingAllocator = SegmentAllocator.slicingAllocator(arena.allocate(size));
    }

    public MemorySegment allocate(long byteSize, long byteAlignment) {
        return slicingAllocator.allocate(byteSize, byteAlignment);
    }

    public MemorySegment.Scope scope() {
        return arena.scope();
    }

    public void close() {
        arena.close();
    }

}
Иными словами, сегментирующая арена обеспечивает значительно более эффективную и масштабируемую стратегию выделения памяти, сохраняя при этом гарантию своевременного освобождения памяти, предоставляемую базовой ограниченной ареной:
try (Arena slicingArena = new SlicingArena(1000)) {
    for (int i = 0; i < 10; i++) {
        MemorySegment s = slicingArena.allocateFrom(JAVA_INT, 1, 2, 3, 4, 5);
        ...
    }
} // all memory allocated is released here
Требования к реализации:
Реализации этого интерфейса являются потокобезопасными.
Начиная с версии:
22
См. также:
  • MemorySegment

Краткое описание методов

Модификатор и тип Метод Описание
MemorySegment allocate(long byteSize, long byteAlignment)
Возвращает сегмент нативной памяти заданного размера (в байтах) и с заданным ограничением на выравнивание (в байтах).
void close()
Закрывает эту арену.
static Arena global()
Возвращает глобальную арену.
static Arena ofAuto()
Создаёт новую арену, управляемую сборщиком мусора автоматически.
static Arena ofConfined()
Возвращает новую ограниченную арену.
static Arena ofShared()
Возвращает новую общую арену.
MemorySegment.Scope scope()
Возвращает область действия арены.

Методы, объявленные в интерфейсе SegmentAllocator

allocate, allocate, allocate, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom, allocateFrom

Подробное описание методов

ofAuto

static Arena ofAuto()
Создаёт новую арену, управляемую сборщиком мусора автоматически. Доступ к сегментам, выделенным с помощью возвращённой арены, может осуществлять любой поток. Вызов close() для возвращённой арены приведёт к возникновению исключения UnsupportedOperationException.

Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.

Возвращает:
новую арену, управляемую сборщиком мусора автоматически

global

static Arena global()
Возвращает глобальную арену. Доступ к сегментам, выделенным с помощью глобальной арены, может осуществлять любой поток. Вызов close() для возвращённой арены приведёт к возникновению исключения UnsupportedOperationException.

Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.

Возвращает:
глобальную арену

ofConfined

static Arena ofConfined()
Возвращает новую ограниченную арену. Доступ к сегментам, выделенным с помощью ограниченной арены, может осуществлять только поток, создавший арену, — поток-владелец арены.

Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.

Возвращает:
новую ограниченную арену

ofShared

static Arena ofShared()
Возвращает новую общую арену. Доступ к сегментам, выделенным с помощью общей арены, может осуществлять любой поток.

Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.

Возвращает:
новую общую арену

allocate

MemorySegment allocate(long byteSize, long byteAlignment)
Возвращает сегмент нативной памяти заданного размера (в байтах) и с заданным ограничением на выравнивание (в байтах). Возвращённый сегмент связан с областью действия арены. address сегмента является начальным адресом выделенной области вне кучи, поддерживающей этот сегмент; этот адрес выравнивается в соответствии с заданным ограничением на выравнивание.
Определено в:
allocate в интерфейсе SegmentAllocator
Требования к реализации:
Реализации этого метода должны возвращать нативный сегмент запрошенного размера, совместимый с заданным ограничением на выравнивание. Кроме того, для любых двух сегментов S1, S2, возвращённых этим методом, должно выполняться следующее условие:
    S1.asOverlappingSlice(S2).isEmpty() == true
Параметры:
byteSize — размер (в байтах) области памяти вне кучи, поддерживающей сегмент нативной памяти
byteAlignment — ограничение на выравнивание (в байтах) области памяти вне кучи, поддерживающей сегмент нативной памяти
Возвращает:
новый сегмент нативной памяти
Выбрасывает:
IllegalArgumentException — если bytesSize < 0, byteAlignment <= 0 или если byteAlignment не является степенью двойки
IllegalStateException — если эта арена уже закрыта
WrongThreadException — если эта арена является ограниченной и метод вызван из потока, отличного от потока-владельца арены

scope

MemorySegment.Scope scope()
Возвращает область действия арены.
Возвращает:
область действия арены

close

void close()
Закрывает эту арену. Если выполнение этого метода завершается нормально, область действия арены больше не является действующей, и доступ ко всем связанным с ней сегментам памяти становится невозможен. Кроме того, освобождаются все области памяти вне кучи, поддерживающие сегменты, полученные из этой арены.
Определено в:
close в интерфейсе AutoCloseable
Примечание API:
Эта операция не является идемпотентной: закрытие уже закрытой арены всегда приводит к выбрасыванию исключения. Это намеренное проектное решение: невозможность закрыть арену может указывать на ошибку в логике базового приложения.
Требования к реализации:
Если выполнение этого метода завершается нормально, то this.scope().isAlive() == false. Если операция явного закрытия не поддерживается, реализации могут выбросить UnsupportedOperationException.
Выбрасывает:
IllegalStateException — если арена уже закрыта
IllegalStateException — если связанный с этой ареной сегмент используется одновременно, например дескриптором метода вызова внизОГРАНИЧЕННЫЙ
WrongThreadException — если эта арена является ограниченной и метод вызван из потока, отличного от потока-владельца арены
UnsupportedOperationException — если эту арену нельзя закрыть явно
RuntimeException — если при выполнении пользовательского действия по очистке, связанного с этой ареной, выбрасывается исключение (например, в результате вызова MemorySegment.reinterpret(long, Arena, Consumer)ОГРАНИЧЕННЫЙ или MemorySegment.reinterpret(Arena, Consumer)ОГРАНИЧЕННЫЙ).
См. также:
  • MemorySegment.Scope.isAlive()

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в разделе Документация Java SE, где приведены более подробные описания для разработчиков, концептуальные обзоры, определения терминов, обходные решения и работающие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её аффилированных лиц в США и других странах.
Авторское право © 1993, 2025, Oracle и/или её аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/foreign/Arena.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API