Spis treści

Nowiutka Java 16 wydana!

Java 16 Duke z balonikami

Spóźniłam się o prawie dwa tygodnie. Java 16 została wydana 16 marca, a dziś jest już 26. Nie szkodzi, nikt nas nie goni, możemy się spokojnie przyjrzeć, co ostatecznie wylądowało w tej wersji.

[TOC]

Nowe wydanie

Tak naprawdę to 16 marca JDK 16 osiągnęło fazę tzw. “General Availability” czyli “Ogólnej Dostępności”; wcześniejsze wersje były oczywiście dostępne jako, kolejno:

  • “rampdown phase one” (2020-12-10)
  • “two” (2021-01-14)
  • “initial RC” (2021-02-04)
  • “final RC” (2021-02-18).

Od jakiegoś czasu wiadomo więc dokładnie, co przynosi ze sobą ostatnia wersja JDK przed oczekiwaną javą 17, która ma być wersją z długookresowym wsparciem (LTS) ze strony Oracle.

Zmiany w środowisku rozwojowym JDK

  • repozytoria społeczności OpenJDK przemigtowano z Mercuriala (hg) do Git-a JEP 357, po czym przeniesiono je do GitHuba (JEP 369); issue tracker został w starej lokalizacji.
  • JEP 347: umożliwiono programistom JDK używania nowych funkcji języka C++14

Wsprcie dla innych architektur

  • port dla Alpine Linux (JEP 386) - dystrybucji szeroko używanej w rozwiązaniach “chmurowych”, mikroserwisach, środowiskach kontenerowych (Alpine Linux na dockerze ma tylko 6MB!)
  • port dla Windows/AArch64 (JEP 388)

Zamykanie “wnętrzności”

  • JEP 396- silne zamknięcie dostępu do wewnętrznego API JDK (poza sun.misc.Unsafe, dla którego nie ma standardowych zamienników):
  • dotychczas programiści mogli korzystać z poluzowania dostępu: domyślną wartością --illegal-access była wartość permit, co oznaczało, że wszystkie pakiety z JDK 8 były otwarte dla kodu w modułach nienazwanych, więc cały kod na classpath miał dostęp przez reflection do niepublicznych pakietów w java., sun. etc (skutkowało to wypisaniem jednego komunikatu przy uruchomieniu kodu)
  • Od JDK16 domyślą opcją --illegal-access będzie deny, chyba że dostęp będzie zagwarantowany z wiersza poleceń opcją --add-opens.

Pakowacz - jpackage

  • JEP 392 - wprowadzenie narzędzia do przygotowywania paczek instalacyjnych, które umożliwi tworzenie “dystrybucji” aplikacji w natywnym dla danej platformy formacie: msi i exe dla Windows, pkg i dmg dla macOS, deb i rpm dla Linuksa.

Zarządanie pamięcią

  • JEP 387 - użycie algorytmu alokacji pamięci buddy memory allocation - wykorzystywanego i sprawdzonego w kernelu Linuksa - do obsługi pamięci “metaspace”, co pozwala na szybsze “oddawanie” nieużywanej, zwolnionej pamięci do systemu operacyjnego.
  • Zmiana ma znaczenie w projektach, w których istnieje wiele, często tworzonych dynamicznie, classloaderów i występuje proces intensywnego, wielokrotnego ładowania/odładowywania klas. Każdy z nich ma przydzielony obszar (tzw. “arenę”) na dane swoich klas, z której szyko (przez przesunięcie wskaźnika) alokuje nowe “chunki” pamięci. Po usunięciu classloadera przypadające na niego “chunki” pamięci trafiają na listę wolnych, czekając na ponowne użycie, co w praktyce może nigdy się nie zdarzyć.
  • Użycie nowego algorytmu zastępuje alokator pamięci metaspace i umożliwia alokacę w mniejszych “chunkach” o tej samiej wielkości, nazwanych “granules”. Zmniejszy to fragmentację i poprawi możliwości oddania systemowi operacyjnemu nieużywanej pamięci.
  • Alokacja pamięci do “aren” będzie się odbywała “leniwie”, na żądanie, co zmniejszy obciążenie pamięci w loaderach, które obecnie zaczynają z wielkimi arenami, ale nie używają ich przez dłuższy czas albo nie używają w ogóle.

GC

  • JEP 376 ZGC ulepsza swoje działanie w obszarze przetwarzania wątków: wiele operacji, których czas działania zależy od wielkości heapa, zostało zaimplementowanych w taki sposób, że odbywają się one równolegle z działającymi wątkami aplikacji, bez konieczności osiągania przez wątki punktów “safepoint”: oznaczanie (marking), przenoszenie, przetwarzanie referencji, odładowywanie klas i większość operacji przetwarzania “gc roots”.

Zmiany w języku

  • w module jdk.incubator.vector znalazła się propozycja API do operacji wektorowych JEP 338; obliczenia wektorowe będą dzięki niemu w przewidywalny sposób kompilowane do specjalnych wektorowch instrukcji sprzętowych (na wspierających takie instrukcje architekturach): SSE oraz AVX. API może w przyszłości wspierać rozszerzenie SVE, choć nie istnieje jeszcze żadna sprzętowa implementacja. JEP 338 skupił się wyłącznie na architekturach x64 i AArch64 (inne będą być może również wspierane w przyszłości)
  • JEP 380 Unix-Domain Socket Channels. Pakiet java.io.channels został poszerzony o możliwość definiowania soketów uniksowych (AF_UNIX). Komunikacja międzyprocesowa na tym samym hoście jest dużo bardziej efektywna przy użyciu soketów lokalnych niż połączeń przy użyciu interfejsu TCP/IP, jest również bezpieczniejsza; gniazda uniksowe, widoczne w systemie plików, podlegają ochronie dostępu tak samo jak zwykłe pliki; mają większą przepustowość i są szybciej tworzone niż gniazda TCP/IP; w systemach kotenerowych sokety tworzone na dzielonych wolumenach na tym samym hoście mogą zwiększyś szybkość komunikacji. Zmiany:
  • do enuma StandardProtocolFamily została dodana, obok INET i INET6, stała UNIX, oznaczająca soket uniksowy
  • została dodana nowa klasa java.net.UnixDomainSocketAddress
  • SocketChannel i ServerSocketChannel mają nową metodę-fabrykę oraz zaktualizowaną specyfikację
  • JEP 395 Rekordy są już oficjalnie częścią języka Java. Zmiany względem wersji preview to:

    • konstruktor - zadeklarowany niejawnie - ma ten sam modyfikator dostępu, co klasa-rekord; jawnie zareklarowany - musi zadeklarować dostęp co najmniej tak szeroki, co klasa-rekord.
    • przypisanie pól w konstruktorze będzie skutkować błędem kompilacji
    • można zadeklarować lokalne klasy-rekordy podobnie jak lokalne klasy-enumy i lokalne interfejsy
    • dodano możliwość deklarowania statycznych memberów klas wewnętrznych (inner); w szczególności będzie można zadeklarować membera, który jest klasą-rekordem.
  • JEP 390 Ostrzeżenia kompilatora w przypadku używania konstruktorów klas-wraperów (java.lang.Integer, java.lang.Double itd.); jest to przygotowanie do wprowadzenia value based classes w ramach projektu Valhalla.