Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A kérdés nem az, hogy a Java 11-es vagy újabb verzióra kell-e váltania, hanem az, hogy mikor. A következő néhány évben a Java 8 már nem támogatott, és a felhasználóknak át kell lépniük a Java 11-be vagy újabb verzióba. Azzal érvelünk, hogy a Java 11-be való áttérésnek vannak előnyei, és arra ösztönözzük a csapatokat, hogy ezt a lehető leghamarabb megtegyünk.
A Java 8 óta új funkciókkal bővültek, és fejlesztéseket hajtottak végre. Az API-hoz jelentős kiegészítések és módosítások tartoznak, és vannak olyan fejlesztések, amelyek javítják az indítást, a teljesítményt és a memóriahasználatot.
Váltás Java 11-re
A Java 11-be való áttérés lépésenkénti módon végezhető el. Ahhoz, hogy a kód futtatható legyen Java 11-en, nem szükséges Java-modulokat használni. A Java 11 a JDK 8-nal kifejlesztett és létrehozott kód futtatására használható. Vannak azonban lehetséges problémák, amelyek elsősorban az elavult API-val, az osztálybetöltőkkel és a tükröződéssel kapcsolatosak.
A Microsoft Java mérnöki csoportja útmutatót kínál a Java 8-ról a Java 11-re való áttéréshez. A Java Platform, a Standard Edition Oracle JDK 9 migrálási útmutatója és a modulrendszer állapota: Kompatibilitás és migrálás más hasznos útmutatók.
Magas szintű változások Java 8 és 11 között
Ez a szakasz nem sorolja fel a Java 9 [1], 10 [2] és 11 [3] verzióiban végrehajtott összes módosítást. A teljesítményre, a diagnosztikára és a termelékenységre hatással lévő változások kiemelten jelennek meg.
Modulok [4]
A modulok olyan konfigurációs és beágyazási problémákat oldanak meg, amelyeket nehéz kezelni az osztályúton futó nagy méretű alkalmazásokban. A modul a Java-osztályok és -felületek, valamint a kapcsolódó erőforrások önleíró gyűjteménye.
A modulok lehetővé teszik olyan futtatókörnyezeti konfigurációk testreszabását, amelyek csak az alkalmazás által igényelt összetevőket tartalmazzák. Ez a testreszabás kisebb erőforrásigényt eredményez, és lehetővé teszi, hogy egy alkalmazás statikusan, jlink használatával egy egyéni futtatókörnyezetbe legyen csatolva az üzembe helyezéshez. Ez a kisebb lábnyom különösen hasznos lehet egy mikroszolgáltatás-architektúrában.
A JVM belsőleg úgy tudja kihasználni a modulok előnyeit, hogy hatékonyabbá teszi az osztálybetöltést. Az eredmény egy kisebb, könnyebb és gyorsabban indítható futtatókörnyezet. A JVM által az alkalmazás teljesítményének javítására használt optimalizálási technikák hatékonyabbak lehetnek, mivel a modulok kódolják az osztály által igényelt összetevőket.
A programozók számára a modulok segítenek az erős beágyazás kikényszerítésében azáltal, hogy explicit deklarációt követelnek meg arról, hogy mely csomagok exportálják a modulokat, és mely összetevőkre van szükség, valamint a tükröző hozzáférés korlátozásával. Ez a beágyazási szint biztonságosabbá és könnyebben karbantarthatóvá teszi az alkalmazásokat.
Az alkalmazások továbbra is használhatják az osztályozót , és nem kell modulokra váltaniuk a Java 11-en való futtatáshoz.
Profilkészítés és diagnosztika
Java Flight Recorder [5]
A Java Flight Recorder (JFR) diagnosztikai és profilkészítési adatokat gyűjt egy futó Java-alkalmazásból. A JFR kevés hatással van egy futó Java-alkalmazásra. Az összegyűjtött adatok ezután elemezhetők a Java Mission Control (JMC) és más eszközök használatával. Míg a JFR és a JMC kereskedelmi funkciók voltak a Java 8-ban, mindkettő nyílt forráskódú a Java 11-ben.
Java Mission Control [6]
A Java Mission Control (JMC) grafikusan jeleníti meg a Java Flight Recorder (JFR) által gyűjtött adatokat, és nyílt forráskódú a Java 11-ben. A futó alkalmazással kapcsolatos általános információk mellett a JMC lehetővé teszi, hogy a felhasználó részletezhesse az adatokat. A JFR és a JMC a futásidejű problémák, például a memóriaszivárgások, a GC többletterhelése, a hot módszerek, a szál szűk keresztmetszete és az I/O blokkolása diagnosztizálására alkalmazható.
Egyesített naplózás [7]
A Java 11 egy közös naplózási rendszerrel rendelkezik a JVM összes összetevőjéhez. Ez az egységes naplózási rendszer lehetővé teszi a felhasználó számára, hogy meghatározza a naplózni kívánt összetevőket, és hogy milyen szinten. Ez a részletes naplózás hasznos a JVM-összeomlások kiváltó okának elemzéséhez és az éles környezetben fellépő teljesítményproblémák diagnosztizálásához.
Alacsony terhelésű halomprofilozás [8]
Új API lett hozzáadva a Java Virtual Machine Tool Interface -hez (JVMTI) a Java-halomfoglalások mintavételezéséhez. A mintavételezés alacsony többletterheléssel rendelkezik, és folyamatosan engedélyezhető. Bár a halomfoglalás a Java Flight Recorderrel (JFR) figyelhető, a JFR-ben a mintavételezési módszer csak a foglalásokon működik. Előfordulhat, hogy a JFR-implementáció figyelmen kívül hagyja a foglalásokat. Ezzel szemben a Java 11-ben a halom mintavételezése élő és holt objektumokról is biztosít információkat.
Az alkalmazásteljesítmény-monitorozás (APM) gyártói kezdik használni ezt az új funkciót, és a Java mérnöki csoport vizsgálja az Azure teljesítményfigyelő eszközeivel való lehetséges használatát.
StackWalker [9]
A naplózás során gyakran történik pillanatkép készítése az aktuális szál vereméről. A probléma az, hogy a verem nyomkövetésének mekkora része legyen naplózva, és hogy egyáltalán naplózza-e a verem nyomkövetését. Előfordulhat például, hogy csak egy bizonyos kivétel esetén szeretné látni egy metódus verem nyomkövetését. A StackWalker osztály (a Java 9-ben hozzáadva) pillanatképet ad a veremről, és olyan módszereket biztosít, amelyekkel a programozó részletesen szabályozhatja a veremkövetés használatát.
Szemétgyűjtés [10]
A következő garbage collectorok érhetők el a Java 11-ben: Serial, Parallel, Garbage-First és Epsilon. A Java 11 alapértelmezett szemétgyűjtője a Garbage First Garbage Collector (G1GC).
Három másik gyűjtőt említenek itt a teljesség érdekében. A Z Szemétgyűjtő (ZGC) egy egyidejű, alacsony késleltetésű gyűjtő, amely 10 ms alatt próbálja tartani a szüneteltetési időket. A ZGC kísérleti funkcióként érhető el a Java 11-ben. A Shenandoah gyűjtő egy rövid szünetidejű gyűjtő, amely csökkenti a GC szüneteltetési idejét azáltal, hogy több szemétgyűjtést végez a futó Java programmal egyidejűleg. A Shenandoah egy kísérleti funkció a Java 12-ben, de vannak a Java 11-be való backportok. Az Egyidejű Jelölő és Takarító gyűjtő (CMS) elérhető, de a Java 9 óta hivatalosan elavult.
A JVM beállítja a GC alapértelmezett értékét az átlagos használati esethez. Ezeket az alapértelmezett beállításokat és más GC-beállításokat gyakran az alkalmazás igényeinek megfelelően kell hangolni az optimális átviteli sebességhez vagy késéshez. A GC megfelelő finomhangolásához a Microsoft Java mérnöki csoport által biztosított szakértelem, a GC részletes ismerete szükséges.
G1GC
A Java 11 alapértelmezett szemétgyűjtője a G1 kukagyűjtő (G1GC). A G1GC célja, hogy egyensúlyt teremtsen a késés és az átviteli sebesség között. A G1 szemétgyűjtő megkísérli elérni a magas átviteli sebességet azáltal, hogy nagy valószínűséggel teljesíti a szünetidő céljait. A G1GC-t úgy tervezték, hogy elkerülje a teljes gyűjteményeket, de ha az egyidejű gyűjtemények nem tudják elég gyorsan visszanyerni a memóriát, a teljes GC tartalék lesz. A teljes GC ugyanazt a számú párhuzamos feldolgozószálat használja, mint a fiatal és vegyes gyűjtemények.
Párhuzamos szemétgyűjtés (GC)
A párhuzamos gyűjtő a Java 8 alapértelmezett gyűjtője. A Parallel GC egy teljesítménynövelő gyűjtő, amely több szálat használ a szemétgyűjtés felgyorsításához.
Epszilon [11]
Az Epsilon szemétgyűjtő kezeli a foglalásokat, de nem szabadít fel memóriát. Ha a halom kimerült, a JVM leáll. Az Epsilon hasznos rövid élettartamú szolgáltatásokhoz és olyan alkalmazásokhoz, amelyekről ismert, hogy szemétmentesek.
Fejlesztések a Docker-tárolókhoz [12]
A Java 10 előtt a JVM nem ismerte fel a tárolón beállított memória- és CPU-korlátozásokat. A Java 8-ban például a JVM alapértelmezés szerint a mögöttes gazdagép fizikai memóriájának 1/4-ére teszi a halom maximális méretét. A Java 10-től kezdve a JVM tárolóvezérlő csoportok (cgroupok) által beállított korlátozásokat használ a memória- és PROCESSZORkorlátok beállításához (lásd az alábbi megjegyzést). Az alapértelmezett maximális halomméret például a tároló memóriakorlátjának 1/4-e (például 500 MB -m2Gesetén).
JVM-beállításokat is hozzáadtunk, hogy a Docker-tároló felhasználói részletesen szabályozhatják a Java-halomhoz használt rendszermemória mennyiségét.
Ez a támogatás alapértelmezés szerint engedélyezve van, és csak Linux-alapú platformokon érhető el.
Megjegyzés:
A csoportengedélyezési munka nagy része a jdk8u191-ből a Java 8-ba lett visszajelentve. A további fejlesztések nem feltétlenül kerülnek vissza a 8-ra.
Tipp
Az alapértelmezett szemétgyűjtő és a JVM számos alapértelmezett beállítása megváltozik a Java 8 és a Java 11 között, így előfordulhat, hogy a Java 8-hoz hangolt beállítások már nem feltétlenül optimálisak. A Java () jaz beolvassa a tároló cgroup memória- és CPU-korlátait, és automatikusan alkalmazza a JDK-verzióra és környezetre szabott JVM-jelzőket. Cserélje le a java parancsot jaz parancsra, hogy kézi újrahangolás nélkül a verziónak megfelelő alapértelmezett beállításokat használja.
Több kiadású jar-fájlok [13]
A Java 11-ben létrehozhat egy jar-fájlt, amely az osztályfájlok több, Java-kiadásra vonatkozó verzióját tartalmazza. A több kiadású jar-fájlok lehetővé teszik a kódtár-fejlesztők számára, hogy a Java több verzióját is támogatják anélkül, hogy több jar-fájlverziót kellene szállítaniuk. Ezeknek a kódtáraknak a felhasználója számára a több kiadású jar-fájlok megoldják azt a problémát, hogy adott jar-fájloknak adott futtatókörnyezeti célokkal kell egyezniük.
Egyéb teljesítménybeli fejlesztések
A JVM következő módosításai közvetlen hatással vannak a teljesítményre.
JEP 197: Szegmentált kódgyorsítótár [14] – A kódgyorsítótárat különböző szegmensekre osztja. Ez a szegmentálás jobban szabályozza a JVM memóriaigényét, lerövidíti a lefordított metódusok vizsgálati idejét, jelentősen csökkenti a kódgyorsítótár töredezettségét, és javítja a teljesítményt.
JEP 254: Kompakt sztringek [15] – A karakterkódolástól függően karakterenként két bájtról egy vagy két bájtra módosítja a sztring belső megjelenítését. Mivel a legtöbb sztring ISO-8859-1/Latin-1 karaktert tartalmaz, ez a változás gyakorlatilag felére csökkenti a sztring tárolásához szükséges térközt.
JEP 310: Alkalmazás Class-Data megosztás [16] – Class-Data megosztás csökkenti az indítási időt azáltal, hogy lehetővé teszi az archivált osztályok futásidőben történő memórialeképezési használatát. Az alkalmazás Class-Data megosztása kibővíti az osztályadatok megosztását azáltal, hogy lehetővé teszi az alkalmazásosztályok CDS-archívumba helyezését. Ha ugyanazon archív fájlt használja több JVM, azzal meg lehet kímélni a memóriát, és így javul a rendszer válaszideje.
JEP 312: Thread-Local kézfogások [17] – Lehetővé teszi a visszahívás végrehajtását a szálakon globális virtuálisgép-biztonsági pont nélkül, amely segít a virtuális gépnek alacsonyabb késést elérni a globális biztonságos pontok számának csökkentésével.
Fordítószálak lusta lefoglalása [18] – Többszintű fordítási módban a virtuális gép számos fordítószálat indít el. Ez a mód az alapértelmezett a sok processzorral rendelkező rendszereken. Ezek a szálak a rendelkezésre álló memóriától és a fordítási kérelmek számától függetlenül jönnek létre. A szálak akkor is használnak memóriát, ha tétlenek (ami szinte mindig), ami az erőforrások nem hatékony használatához vezet. A probléma megoldásához az implementáció úgy módosult, hogy az indítás során csak egy fordítószál induljon el az egyes típusok közül. A további szálak indítása és a nem használt szálak leállítása dinamikusan történik.
Az alapvető kódtárak alábbi módosításai hatással vannak az új vagy módosított kódok teljesítményére.
JEP 193: Változófogópontok [19] – Szabványos eszközt határoz meg a különböző java.util.concurrent.atomic és sun.misc.Unsafe műveletek megfelelőinek meghívására az objektummezőkön és tömbelemeken, valamint egy szabványos kerítésművelet készletet a memóriarendezés finomszemcsés vezérlésére, és egy szabványos elérhetőségi kerítési műveletet, amely biztosítja, hogy a hivatkozott objektum erősen elérhető maradjon.
JEP 269: Convenience Factory Methods for Collections [20] – Kódtár API-jait határozza meg, hogy a gyűjtemények és térképek példányainak létrehozása kényelmes legyen kis számú elemből. A kompakt, nem módosítható gyűjteménypéldányokat létrehozó gyűjtőfelületeken található statikus gyári metódusok. Ezek a példányok természetüknél fogva hatékonyabbak. Az API-k olyan gyűjteményeket hoznak létre, amelyek tömören vannak ábrázolva, és nem rendelkeznek burkolóosztálysal.
JEP 285: Spin-Várakozási Tipp [21] – API-t biztosít, amely lehetővé teszi a Java számára, hogy jelezze a futásidejű rendszernek, hogy egy pörgő ciklusban van. Bizonyos hardverplatformok esetében a szoftver azt jelzi, hogy egy szál aktív várakozási állapotban van.
JEP 321: HTTP-ügyfél (Standard) [22]– Új HTTP-ügyfél API-t biztosít, amely a HTTP/2-t és a WebSocketet implementálja, és képes lecserélni az örökölt HttpURLConnection API-t.
Hivatkozások
[1] Oracle Corporation, "Java Development Kit 9 Release Notes" (Online). Elérhető: https://www.oracle.com/technetwork/java/javase/9u-relnotes-3704429.html. (Hozzáférés: 2019. november 13.)
[2] Oracle Corporation, "Java Development Kit 10 Kiadási megjegyzések" (Online). Elérhető: https://www.oracle.com/technetwork/java/javase/10u-relnotes-4108739.html. (Hozzáférés: 2019. november 13.)
[3] Oracle Corporation, "Java Development Kit 11 Release Notes" (Online). Elérhető: https://www.oracle.com/technetwork/java/javase/11u-relnotes-5093844.html. (Hozzáférés: 2019. november 13.)
[4] Oracle Corporation, "Project Jigsaw", 2017. szeptember 22. (Online). Elérhető: http://openjdk.java.net/projects/jigsaw/. (Hozzáférés: 2019. november 13.)
[5] Oracle Corporation, "JEP 328: Flight Recorder", 2018. szeptember 9. (Online). Elérhető: http://openjdk.java.net/jeps/328. (Hozzáférés: 2019. november 13.)
[6] Oracle Corporation, "Mission Control", 2019. április 25. (Online). Elérhető: https://wiki.openjdk.java.net/display/jmc/Main. (Hozzáférés: 2019. november 13.)
[7] Oracle Corporation, "JEP 158: Unified JVM Logging", 2019. február 14. (Online). Elérhető: http://openjdk.java.net/jeps/158. (Hozzáférés: 2019. november 13.)
[8] Oracle Corporation, „JEP 331: Low-Overhead Heap Profiling”, 2018. szeptember 5. (Online). Elérhető: http://openjdk.java.net/jeps/331. (Hozzáférés: 2019. november 13.)
[9] Oracle Corporation, "JEP 259: Stack-Walking API", 2017. július 18. (Online). Elérhető: http://openjdk.java.net/jeps/259. (Hozzáférés: 2019. november 13.)
[10] Oracle Corporation, „JEP 248: Make G1 the Default Garbage Collector,” 2017. szeptember 12. (Online). Elérhető: http://openjdk.java.net/jeps/248. (Hozzáférés: 2019. november 13.)
[11] Oracle Corporation, „JEP 318: Epsilon: A No-Op Garbage Collector”, 2018. szeptember 24. (Online). Elérhető: http://openjdk.java.net/jeps/318. (Hozzáférés: 2019. november 13.)
[12] Oracle Corporation, "JDK-8146115: A Docker-tároló észlelésének és az erőforrás-konfiguráció használatának javítása", 2019. szeptember 16. (Online). Elérhető: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8146115. (Hozzáférés: 2019. november 13.)
[13] Oracle Corporation, "JEP 238: Multi-Release JAR Files", 2017. június 22. (Online). Elérhető: http://openjdk.java.net/jeps/238. (Hozzáférés: 2019. november 13.)
[14] Oracle Corporation, "JEP 197: Szegmentált kódgyorsítótár", 2017. április 28. (Online). Elérhető: http://openjdk.java.net/jeps/197. (Hozzáférés: 2019. november 13.)
[15] Oracle Corporation, "JEP 254: Compact Strings", 2019. május 18. (Online). Elérhető: http://openjdk.java.net/jeps/254. (Hozzáférés: 2019. november 13.)
[16] Oracle Corporation, „JEP 310: Application Class-Data Sharing,” 2018. augusztus 17. (Online). Elérhető: https://openjdk.java.net/jeps/310. (Hozzáférés: 2019. november 13.)
[17] Oracle Corporation, "JEP 312: Thread-Local Handshakes," August 21, 2019. (Online). Elérhető: https://openjdk.java.net/jeps/312. (Hozzáférés: 2019. november 13.)
[18] Oracle Corporation, "JDK-8198756: A fordítószálak késleltetett lefoglalása", 2018. október 29. (Online). Elérhető: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8198756. (Hozzáférés: 2019. november 13.)
[19] Oracle Corporation, "JEP 193: Variable Handles", 2017. augusztus 17. (Online). Elérhető: https://openjdk.java.net/jeps/193. (Hozzáférés: 2019. november 13.)
[20] Oracle Corporation, „JEP 269: Convenience Factory Methods for Collections”, június 26., 2017. (Online). Elérhető: https://openjdk.java.net/jeps/269. (Hozzáférés: 2019. november 13.)
[21] Oracle Corporation, "JEP 285: Spin-Wait Tippek", 2017. augusztus 20. (Online). Elérhető: https://openjdk.java.net/jeps/285. (Hozzáférés: 2019. november 13.)
[22] Oracle Corporation, "JEP 321: HTTP Client (Standard)," 2018. szeptember 27. (Online). Elérhető: https://openjdk.java.net/jeps/321. (Hozzáférés: 2019. november 13.)