Интерфейс 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 |
allocate |
Возвращает сегмент нативной памяти заданного размера (в байтах) и с заданным ограничением на выравнивание (в байтах). |
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 |
Возвращает новый сегмент памяти с заданным byteSize. |
default MemorySegment |
allocate |
Возвращает новый сегмент памяти с заданной раскладкой. |
default MemorySegment |
allocate |
Возвращает новый сегмент памяти с заданными elementLayout и count. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный адресом указанного сегмента памяти. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа byte. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива byte. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа char. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива char. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа double. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива double. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа float. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива float. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа int. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива int. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа long. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива long. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный указанным значением типа short. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный элементами указанного массива short. |
default MemorySegment |
allocateFrom |
Возвращает новый сегмент памяти, инициализированный содержимым указанного сегмента. |
default MemorySegment |
allocateFrom |
Преобразует строку Java в строку C с завершающим нулевым символом, используя кодировку UTF-8, и сохраняет результат в сегменте памяти. |
default MemorySegment |
allocateFrom |
Преобразует строку Java в строку C с завершающим нулевым символом, используя указанную кодировку, и сохраняет результат в сегменте памяти. |
default MemorySegment |
allocateFrom |
Кодирует строку Java с помощью указанной кодировки и сохраняет полученный массив байтов в сегменте памяти. |
Подробное описание методов
ofAuto
static Arena ofAuto()
close() для возвращённой арены приведёт к возникновению UnsupportedOperationException. Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.
- Возвращает:
- новую арену, управляемую сборщиком мусора автоматически
global
static Arena global()
close() для возвращённой арены приведёт к возникновению UnsupportedOperationException. Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.
- Возвращает:
- глобальную арену
ofConfined
static Arena ofConfined()
Сегменты памяти, выделенные возвращённой ареной, инициализируются нулями.
- Возвращает:
- новую арену с ограничением по потоку
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)ОГРАНИЧЕННЫЙ). - См. также:
© 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.