MemorySegment i Arena
Alokowanie pamięci poza stertą
MemorySegment i Arena to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Pamięć poza stertą
FFM odwzorowuje natywną pamięć poza stertą za pomocą dwóch podstawowych typów: MemorySegment reprezentuje ciągły obszar pamięci, a Arena kontroluje jego czas życia.
Razem zastępują niebezpieczne, ręczne zarządzanie buforami stosowane w przeszłości.
Czym jest MemorySegment
MemorySegment to typowany widok na blok pamięci. Zna swój rozmiar i czas życia, a każdy dostęp jest sprawdzany pod kątem zakresu.
Segmenty mogą znajdować się poza stertą (w pamięci natywnej) lub opakowywać tablicę na stercie.
Czym jest Arena
Arena przydziela segmenty i określa, kiedy zostaną zwolnione. Po zamknięciu obiektu arena wszystkie jego segmenty stają się nieprawidłowe w jednym deterministycznym kroku.
Arena.ofConfined(): jeden wątek, jawne zamknięcieArena.ofShared(): dostęp z wielu wątkówArena.global(): nigdy nie jest zwalnianyArena.ofAuto(): zwalniany przez GC
Przydzielanie segmentu
Typowym wzorcem jest ograniczony obiekt arena w konstrukcji try-with-resources. Należy przydzielić bajty, użyć ich, a zamknięcie zwolni całość.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
try (Arena arena = Arena.ofConfined()) {
MemorySegment seg = arena.allocate(16);
System.out.println("Allocated bytes: " + seg.byteSize());
}
System.out.println("Arena closed, memory freed");
}
}Zapisywanie i odczytywanie
Odczyt i zapis odbywa się za pomocą typowanych akcesorów, które przyjmują obiekt ValueLayout i przesunięcie. Dzięki temu dostęp jest bezpieczny typowo i prawidłowo wyrównany.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
try (Arena arena = Arena.ofConfined()) {
MemorySegment seg = arena.allocate(ValueLayout.JAVA_INT);
seg.set(ValueLayout.JAVA_INT, 0, 42);
int value = seg.get(ValueLayout.JAVA_INT, 0);
System.out.println("Stored and read: " + value);
}
}
}Przydzielanie typowanych miejsc
Zamiast podawać surową liczbę bajtów, należy przydzielać pamięć według layoutu. arena.allocate(JAVA_INT) rezerwuje dokładnie tyle prawidłowo wyrównanych bajtów, ile potrzeba na jedną wartość typu int.
Eliminuje to konieczność ręcznego obliczania rozmiaru.
Tablice wartości
Aby przechować kilka elementów, należy przydzielić layout sekwencji lub przekazać ich liczbę. Dostęp do indeksu korzysta z przesunięcia obliczonego na podstawie rozmiaru elementu.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
try (Arena arena = Arena.ofConfined()) {
MemorySegment ints = arena.allocate(ValueLayout.JAVA_INT, 5);
for (int i = 0; i < 5; i++) {
ints.setAtIndex(ValueLayout.JAVA_INT, i, i * 10);
}
System.out.println("Element 3: " + ints.getAtIndex(ValueLayout.JAVA_INT, 3));
}
}
}Sprawdzanie zakresu
Odczyt lub zapis poza segmentem powoduje zgłoszenie wyjątku IndexOutOfBoundsException. Dostęp do segmentu po zamknięciu jego obiektu arena powoduje zgłoszenie wyjątku IllegalStateException.
To właśnie te kontrole sprawiają, że pamięć FFM jest bezpieczna, w przeciwieństwie do JNI.
Izolacja
Ograniczony obiekt arena wiąże swoje segmenty z wątkiem, który go utworzył. Próba uzyskania do nich dostępu z innego wątku powoduje zgłoszenie wyjątku WrongThreadException.
W przypadku pamięci, która rzeczywiście ma być współdzielona, należy użyć Arena.ofShared(). Pozwala ono na dostęp z wielu wątków za niewielką cenę.
Praca z napisami
FFM udostępnia pomocnicze metody do konwersji między napisami Javy i napisami C. allocateUtf8String (w nowszych wersjach: allocateFrom) zapisuje napis zakończony bajtem null, a getUtf8String odczytuje go z powrotem.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
try (Arena arena = Arena.ofConfined()) {
MemorySegment cString = arena.allocateUtf8String("hello");
System.out.println("Read back: " + cString.getUtf8String(0));
}
}
}Wybór obiektu Arena
Wskazówki:
- Krótkotrwałe bufory używane przez jeden wątek:
ofConfined() - Bufory współdzielone między wątkami:
ofShared() - Czas życia zarządzany przez GC:
ofAuto() - Stałe obowiązujące w całym procesie:
global()
Szybkie sprawdzenie
Proszę przypomnieć sobie, co określa moment zwolnienia pamięci natywnej.
Podsumowanie
Dowiedzieli się Państwo, jak zarządzać pamięcią poza stertą:
MemorySegment: obszar pamięci ze sprawdzaniem zakresuArena: kontroluje czas życia (ograniczony, współdzielony, automatyczny lub globalny)- Typowany dostęp za pomocą
ValueLayout, metodget/setorazgetAtIndex - Bezpieczeństwo zapewniane przez sprawdzanie zakresu i izolację
Następnie: wywoływanie funkcji natywnych za pomocą uchwytów downcall.
Często zadawane pytania
Czy lekcja „MemorySegment i Arena” jest bezpłatna?
Tak — pełny tekst „MemorySegment i Arena” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „MemorySegment i Arena”?
Alokowanie pamięci poza stertą Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „MemorySegment i Arena”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Dlaczego FFM zamiast JNI
- MemorySegment i Arena
- Uchwyty downcall
- Układy pamięci i struktury