Spec-Zone.ru › OpenJDK 27

Интерфейс 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, allocateFrom
Модификатор и тип Метод Описание
default MemorySegment allocate(long byteSize)
Возвращает новый сегмент памяти с заданным byteSize.
default MemorySegment allocate(MemoryLayout layout)
Возвращает новый сегмент памяти с заданной раскладкой.
default MemorySegment allocate(MemoryLayout elementLayout, long count)
Возвращает новый сегмент памяти с заданными elementLayout и count.
default MemorySegment allocateFrom(AddressLayout layout, MemorySegment value)
Возвращает новый сегмент памяти, инициализированный адресом указанного сегмента памяти.
default MemorySegment allocateFrom(ValueLayout.OfByte layout, byte value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа byte.
default MemorySegment allocateFrom(ValueLayout.OfByte elementLayout, byte... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива byte.
default MemorySegment allocateFrom(ValueLayout.OfChar layout, char value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа char.
default MemorySegment allocateFrom(ValueLayout.OfChar elementLayout, char... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива char.
default MemorySegment allocateFrom(ValueLayout.OfDouble layout, double value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа double.
default MemorySegment allocateFrom(ValueLayout.OfDouble elementLayout, double... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива double.
default MemorySegment allocateFrom(ValueLayout.OfFloat layout, float value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа float.
default MemorySegment allocateFrom(ValueLayout.OfFloat elementLayout, float... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива float.
default MemorySegment allocateFrom(ValueLayout.OfInt layout, int value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа int.
default MemorySegment allocateFrom(ValueLayout.OfInt elementLayout, int... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива int.
default MemorySegment allocateFrom(ValueLayout.OfLong layout, long value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа long.
default MemorySegment allocateFrom(ValueLayout.OfLong elementLayout, long... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива long.
default MemorySegment allocateFrom(ValueLayout.OfShort layout, short value)
Возвращает новый сегмент памяти, инициализированный указанным значением типа short.
default MemorySegment allocateFrom(ValueLayout.OfShort elementLayout, short... elements)
Возвращает новый сегмент памяти, инициализированный элементами указанного массива short.
default MemorySegment allocateFrom(ValueLayout elementLayout, MemorySegment source, ValueLayout sourceElementLayout, long sourceOffset, long elementCount)
Возвращает новый сегмент памяти, инициализированный содержимым указанного сегмента.
default MemorySegment allocateFrom(String str)
Преобразует строку Java в строку C с завершающим нулевым символом, используя кодировку UTF-8, и сохраняет результат в сегменте памяти.
default MemorySegment allocateFrom(String str, Charset charset)
Преобразует строку Java в строку C с завершающим нулевым символом, используя указанную кодировку, и сохраняет результат в сегменте памяти.
default MemorySegment allocateFrom(String str, Charset charset, int srcIndex, int numChars)
Кодирует строку Java с помощью указанной кодировки и сохраняет полученный массив байтов в сегменте памяти.

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

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, 2026, 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.

Spec-Zone.ru

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