Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Otázka není, pokud byste měli přejít na Javu 11 nebo novější verzi, ale kdy. V následujících několika letech se už Java 8 nebude podporovat a uživatelé budou muset přejít na Javu 11 nebo novější. Tvrdíme, že přechod na Javu 11 přináší výhody a podporujeme týmy, aby to udělaly co nejdříve.
Od Javy 8 byly přidány nové funkce a vylepšení. K dispozici jsou znatelné doplňky a úpravy rozhraní API a existují vylepšení, která zlepšují využití spouštění, výkonu a paměti.
Přechod na Javu 11
Přechod na Javu 11 je možné provést krokově. Není nutné, aby kód používal moduly Java ke spuštění v Javě 11. Javu 11 je možné použít ke spouštění kódu vyvinutého a vytvořeného pomocí sady JDK 8. Existují ale některé potenciální problémy, zejména pokud jde o zastaralé rozhraní API, zavaděče tříd a reflexi.
Technická skupina Microsoft Java má průvodce přechodem z Javy 8 na Javu 11. Příručka k migraci Oracle JDK 9 a stav systému modulů v javě, standardní edice Oracle JDK 9: Kompatibilita a migrace jsou další užitečné příručky.
Změny na vysoké úrovni mezi Javou 8 a 11
Tato část nevypíše všechny změny provedené ve verzích Java 9 [1], 10 [2] a 11 [3]. Zvýrazní se změny, které mají vliv na výkon, diagnostiku a produktivitu.
Moduly [4]
Moduly řeší problémy s konfigurací a zapouzdřením, které je obtížné spravovat v rozsáhlých aplikacích běžících na classpath. Modul je samopisující kolekce tříd a rozhraní Java a souvisejících prostředků.
Moduly umožňují přizpůsobit konfigurace modulu runtime, které obsahují pouze komponenty vyžadované aplikací. Toto přizpůsobení vytvoří menší nároky a umožní staticky propojit aplikaci pomocí jlinku do vlastního modulu runtime pro nasazení. Tento menší prostor může být zvlášť užitečný v architektuře mikroslužeb.
Interně JVM využívá moduly způsobem, který zefektivňuje načítání tříd do paměti. Výsledkem je runtime, který je menší, lehčí a rychleji se spouští. Techniky optimalizace používané prostředím JVM ke zlepšení výkonu aplikace mohou být efektivnější, protože moduly kódují komponenty, které třída vyžaduje.
Pro programátory moduly pomáhají vynucovat silné zapouzdření tím, že vyžadují explicitní deklaraci toho, které balíčky modul exportuje a které komponenty vyžaduje, a omezením reflexního přístupu. Díky této úrovni zapouzdření je aplikace bezpečnější a snadněji udržovat.
Aplikace může dál používat třídní cestu a nemusí přecházet na moduly jako nezbytný krok pro běh na Javě 11.
Profilace a diagnostika
Java Flight Recorder [5]
Java Flight Recorder (JFR) shromažďuje diagnostická a profilovací data ze spuštěné aplikace Java. JFR má malý vliv na spuštěnou aplikaci v Javě. Shromážděná data je pak možné analyzovat pomocí Java Mission Control (JMC) a dalších nástrojů. Zatímco JFR a JMC byly komerční funkce v Javě 8, oba jsou open source v Javě 11.
Java Mission Control [6]
Java Mission Control (JMC) poskytuje grafické zobrazení dat shromážděných nástrojem Java Flight Recorder (JFR) a je open source v Javě 11. Kromě obecných informací o spuštěné aplikaci umožňuje JMC uživateli přejít k podrobnostem o datech. JFR a JMC je možné použít k diagnostice problémů za běhu, jako jsou úniky paměti, režie GC, horké metody, úzká místa vláken a blokující I/O.
Jednotné protokolování [7]
Java 11 má společný systém protokolování pro všechny komponenty prostředí JVM. Tento jednotný systém protokolování umožňuje uživateli definovat, které komponenty se mají protokolovat a na jakou úroveň. Toto podrobné protokolování je užitečné pro provádění analýzy původní příčiny v prostředí JVM a pro diagnostiku problémů s výkonem v produkčním prostředí.
Profilace haldy s nízkou režií [8]
Do rozhraní Java Virtual Machine Tool Interface (JVMTI) bylo přidáno nové rozhraní API pro samplování alokace Java heapu. Vzorkování má nízkou režii a dá se povolit nepřetržitě. Alokaci haldy je možné monitorovat pomocí JFR (Java Flight Recorder), ovšem metoda vzorkování v JFR funguje pouze na alokacích. Implementace JFR může také vynechat alokace. Naproti tomu vzorkování haldy v Javě 11 může poskytovat informace o živých i mrtvých objektech.
Dodavatelé APM (Application Performance Monitoring) začínají tuto novou funkci využívat a technická skupina Java zkoumá její potenciální využití s nástroji pro monitorování výkonu Azure.
StackWalker [9]
Získání snímku zásobníku pro aktuální vlákno se často používá při protokolování. Problémem je, kolik trasování zásobníku se má protokolovat a jestli se má trasování zásobníku vůbec protokolovat. Můžete například chtít zobrazit trasování zásobníku pouze pro určitou výjimku z metody. Třída StackWalker (přidaná v Javě 9) poskytuje snímek zásobníku a nabízí metody, které programátorovi umožňují detailní kontrolu nad tím, jak využívat sledování zásobníku.
Uvolňování paměti [10]
V Javě 11 jsou k dispozici následující garbage collectory: Serial, Parallel, Garbage-First a Epsilon. Výchozím systémem správy paměti v Javě 11 je Garbage First Garbage Collector (G1GC).
Jsou zde zmíněni tři další kolektory pro úplnost. Z Garbage Collector (ZGC) je souběžný kolektor s nízkou latencí, který se pokouší udržet dobu pozastavení pod 10 ms. ZGC je k dispozici jako experimentální funkce v Javě 11. Kolekce Shenandoah je kolektor s nízkým pozastavením, který snižuje dobu pozastavení uvolňování paměti prováděním více uvolňování paměti současně se spuštěným programem Java. Shenandoah je experimentální funkce v Javě 12, ale existují backporty k Javě 11. Sběrač Concurrent Mark and Sweep (CMS) je dostupný, ale od Java 9 je zastaralý.
JVM nastaví výchozí hodnoty GC pro průměrný případ použití. Tyto výchozí hodnoty a další nastavení GC je často potřeba ladit pro optimální propustnost nebo latenci podle požadavků aplikace. Správné ladění GC vyžaduje hluboké znalosti GC, odborné znalosti, které poskytuje technická skupina Microsoft Java .
G1GC
Výchozí garbage collector v Javě 11 je garbage collector G1 (G1GC). Cílem G1GC je dosáhnout rovnováhy mezi latencí a propustností. G1 garbage collector se pokouší dosáhnout vysoké propustnosti splněním cílů pro pauzovací časy s vysokou pravděpodobností. G1GC je navržený tak, aby se vyhnul úplným kolekcím, ale když souběžné kolekce nemohou uvolnit paměť dostatečně rychle, bude vyvolána záložní úplná kolekce. Úplné uvolňování paměti (full GC) používá stejný počet paralelních pracovních vláken jako mladší a smíšené kolekce.
Paralelní GC
Paralelní kolektor je výchozí kolektor v Javě 8. Paralelní GC je sběrač, který používá více vláken ke zrychlení uvolňování paměti.
Epsilon [11]
Systém uvolňování paměti Epsilon provádí alokace, ale neobnovuje žádnou paměť. Po vyčerpání haldy se Java Virtual Machine (JVM) vypne. Epsilon je užitečný pro krátkodobé služby a pro aplikace, které jsou známé tím, že nevytvářejí odpad.
Vylepšení kontejnerů Dockeru [12]
Před Verzí Java 10 se prostředí JVM nerozpoznalo omezení paměti a procesoru nastavené na kontejneru. V Javě 8 například JVM nastaví maximální velikost haldy na 1/4 fyzické paměti základního hostitele. Počínaje Javou 10 používá JVM omezení nastavená skupinami řízení kontejnerů (cgroups) k nastavení limitů paměti a procesoru (viz následující poznámka). Výchozí maximální velikost haldy je například 1/4 limitu paměti kontejneru (například 500 MB pro -m2G).
Přidali jsme také možnosti prostředí JVM, které uživatelům kontejneru Dockeru umožňují jemně odstupňovanou kontrolu nad množstvím systémové paměti, která se bude používat pro haldu Java.
Tato podpora je ve výchozím nastavení povolená a je dostupná pouze na platformách založených na Linuxu.
Poznámka:
Většina práce na povolení cgroup byla zpětně přenesena do Javy 8 v rámci jdk8u191. Další vylepšení nemusí být nutně backportována na 8.
Tip
Výchozí systém uvolňování paměti a mnoho výchozích hodnot prostředí JVM se mění mezi Java 8 a Java 11, takže nastavení, která jste naladili pro Java 8, už nemusí být optimální. Spouštěč příkazů Azure pro Java (jaz) přečte limity paměti a procesoru kontejneru cgroup a použije příznaky JVM přizpůsobené verzi a prostředí JDK automaticky.
java Nahraďte příkazem jaz pro získání výchozích hodnot odpovídajících verzím bez ručního přeladění.
Soubory JAR s více verzemi [13]
V Javě 11 je možné vytvořit soubor JAR, který obsahuje více verzí souborů tříd specifických pro javu. Soubory JAR s více verzemi umožňují vývojářům knihoven podporovat více verzí Javy, aniž by museli dodávat více verzí souborů JAR. Pro příjemce těchto knihoven řeší soubory JAR s více verzemi problém, kdy se musí určité soubory JAR shodovat s konkrétními cíli modulu runtime.
Různá vylepšení výkonu
Následující změny prostředí JVM mají přímý dopad na výkon.
JEP 197: Segmentovaná mezipaměť kódu [14] – rozdělí mezipaměť kódu do různých segmentů. Tato segmentace poskytuje lepší kontrolu nad nároky paměti JVM, zkracuje dobu skenování kompilovaných metod, výrazně snižuje fragmentaci mezipaměti kódu a zlepšuje výkon.
JEP 254: Kompaktní řetězce [15] – Změní vnitřní reprezentaci řetězce ze dvou bajtů na znak na jeden nebo dva bajty na znak v závislosti na kódování znaků. Vzhledem k tomu, že většina řetězců obsahuje znaky ISO-8859-1/Latin-1, tato změna efektivně sníží velikost místa potřebného k uložení řetězce.
JEP 310: Sdílení dat tříd aplikací [16] – Sdílení dat tříd zkracuje dobu spuštění tím, že umožňuje, aby archivované třídy byly při běhu mapovány do paměti. Sdílení dat tříd v aplikaci Class-Data Sharing rozšiřuje sdílení dat tříd tím, že umožňuje umístění aplikačních tříd do archivu CDS. Pokud více počítačů JVM sdílí stejný archivní soubor, uloží se paměť a celková doba odezvy systému se zlepší.
JEP 312: Thread-Local handshakes [17] – Umožňuje spustit zpětné volání na vláknech bez provedení globálního bezpečného bodu virtuálního počítače, což pomáhá virtuálnímu počítači dosáhnout nižší latence snížením počtu globálních bezpečných bodů.
Líné alokování vláken kompilátoru [18] – Ve vrstvené kompilaci VM spustí velký počet vláken kompilátoru. Tento režim je výchozí v systémech s mnoha procesory. Tato vlákna se vytvářejí bez ohledu na dostupnou paměť nebo počet požadavků na kompilaci. Vlákna spotřebovávají paměť i v případě, že jsou nečinná (což je téměř vždy), což vede k neefektivnímu využití prostředků. Aby bylo možné tento problém vyřešit, implementace byla změněna tak, aby během spouštění spustila pouze jedno vlákno kompilátoru každého typu. Spouštění dalších vláken a vypnutí nepoužívaných vláken se zpracovává dynamicky.
Následující změny základních knihoven mají vliv na výkon nového nebo upraveného kódu.
JEP 193: Proměnné obslužné rutiny [19] – Definuje standardní způsob vyvolání ekvivalentů různých operací java.util.concurrent.atomic a sun.misc.Unsafe na objektových polích a prvcích pole, standardní sadu operací plotu pro jemně odstupňovanou kontrolu řazení paměti a standardní operaci dosažitelnosti plotu, která zajistí, že odkazovaný objekt zůstane silně dosažitelný.
JEP 269: Convenience Factory Methods for Collections [20] – Definuje rozhraní API knihovny, aby bylo vhodné vytvářet instance kolekcí a map s malým počtem prvků. Statické tovární metody na rozhraních kolekcí, které vytvářejí kompaktní a nemodifikovatelné instance kolekcí. Tyto instance jsou ze své podstaty efektivnější. Rozhraní API vytváří kolekce, které jsou kompaktně reprezentovány bez třídy obálky.
JEP 285: Spin-Wait Hints [21] – poskytuje rozhraní API, které umožňuje Java poskytnout systému za běhu indikaci, že se nachází ve spinové smyčce. Některé hardwarové platformy mohou mít prospěch z toho, že software indikuje, že vlákno je ve stavu aktivního čekání.
JEP 321: Klient HTTP (Standard) [22]- Poskytuje nové rozhraní API klienta HTTP, které implementuje protokol HTTP/2 a WebSocket a může nahradit starší rozhraní HTTPURLConnection API.
Odkazy
[1] Oracle Corporation, "Java Development Kit 9 Release Notes" (Online). K dispozici: https://www.oracle.com/technetwork/java/javase/9u-relnotes-3704429.html. (Přístup k 13. listopadu 2019)
[2] Oracle Corporation, "Java Development Kit 10 Release Notes" (Online). K dispozici: https://www.oracle.com/technetwork/java/javase/10u-relnotes-4108739.html. (Přístup k 13. listopadu 2019)
[3] Oracle Corporation, "Java Development Kit 11 Release Notes" (Online). K dispozici: https://www.oracle.com/technetwork/java/javase/11u-relnotes-5093844.html. (Přístup k 13. listopadu 2019)
[4] Oracle Corporation, "Project Jigsaw", září 22, 2017. (Online). K dispozici: http://openjdk.java.net/projects/jigsaw/. (Přístup k 13. listopadu 2019)
[5] Oracle Corporation, "JEP 328: Flight Recorder", září 9, 2018. (Online). K dispozici: http://openjdk.java.net/jeps/328. (Přístup k 13. listopadu 2019)
[6] Oracle Corporation, "Mission Control", 25. dubna 2019. (Online). K dispozici: https://wiki.openjdk.java.net/display/jmc/Main. (Přístup k 13. listopadu 2019)
[7] Oracle Corporation, "JEP 158: Unified JVM Logging", 14. února 2019. (Online). K dispozici: http://openjdk.java.net/jeps/158. (Přístup k 13. listopadu 2019)
[8] Oracle Corporation, "JEP 331: Profilování haldy s nízkou režijní náročností", 5. září 2018. (Online). K dispozici: http://openjdk.java.net/jeps/331. (Přístup k 13. listopadu 2019)
[9] Oracle Corporation, "JEP 259: Stack-Walking API", 18. července 2017. (Online). K dispozici: http://openjdk.java.net/jeps/259. (Přístup k 13. listopadu 2019)
[10] Oracle Corporation, „JEP 248: Make G1 the Default Garbage Collector,“ 12. září 2017. (Online). K dispozici: http://openjdk.java.net/jeps/248. (Přístup k 13. listopadu 2019)
[11] Oracle Corporation, "JEP 318: Epsilon: A No-Op Garbage Collector," 24. září 2018. (Online). K dispozici: http://openjdk.java.net/jeps/318. (Přístup k 13. listopadu 2019)
[12] Oracle Corporation, "JDK-8146115: Zlepšení detekce kontejnerů Dockeru a využití konfigurace prostředků", 16. září 2019. (Online). K dispozici: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8146115. (Přístup k 13. listopadu 2019)
[13] Společnost Oracle Corporation, "JEP 238: Multi-Release JAR Files", 22. června 2017. (Online). K dispozici: http://openjdk.java.net/jeps/238. (Přístup k 13. listopadu 2019)
[14] Oracle Corporation, "JEP 197: Segmented Code Cache", 28. dubna 2017. (Online). K dispozici: http://openjdk.java.net/jeps/197. (Přístup k 13. listopadu 2019)
[15] Oracle Corporation, "JEP 254: Compact Strings", 18. května 2019. (Online). K dispozici: http://openjdk.java.net/jeps/254. (Přístup k 13. listopadu 2019)
[16] Oracle Corporation, "JEP 310: Application Class-Data Sharing," 17. srpna 2018. (Online). K dispozici: https://openjdk.java.net/jeps/310. (Přístup k 13. listopadu 2019)
[17] Oracle Corporation, "JEP 312: Thread-Local Handshakes," 21. srpna 2019. (Online). K dispozici: https://openjdk.java.net/jeps/312. (Přístup k 13. listopadu 2019)
[18] Oracle Corporation, "JDK-8198756: Opožděné přidělování vláken kompilátoru", 29. října 2018. (Online). K dispozici: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8198756. (Přístup k 13. listopadu 2019)
[19] Oracle Corporation, "JEP 193: Variable Handles", 17. srpna 2017. (Online). K dispozici: https://openjdk.java.net/jeps/193. (Přístup k 13. listopadu 2019)
[20] Oracle Corporation, "JEP 269: Convenience Factory Methods for Collections", 26. června 2017. (Online). K dispozici: https://openjdk.java.net/jeps/269. (Přístup k 13. listopadu 2019)
[21] Oracle Corporation, "JEP 285: Spin-Wait Hints", 20. srpna 2017. (Online). K dispozici: https://openjdk.java.net/jeps/285. (Přístup k 13. listopadu 2019)
[22] Oracle Corporation, "JEP 321: HTTP Client (Standard)," 27. září 2018. (Online). K dispozici: https://openjdk.java.net/jeps/321. (Přístup k 13. listopadu 2019)