JDK 16: De nya funktionerna i Java 16

Java Development Kit (JDK) 16 har nått sin inledande rampdown-fas, vilket innebär att funktionsuppsättningen nu är frusen från och med den 10 december 2020. De nya funktionerna i JDK 16 sträcker sig från en andra förhandsvisning av förseglade klasser till mönstermatchning till samtidig tråd- stackbearbetning för sopuppsamling.

JDK 16 kommer att vara referensimplementeringen av den version av standard Java som ska följa JDK 15, som anlände 15 september. I ett föreslaget släppschema har JDK 16 nått en andra rampdown-fas den 14 januari 2021, följt av släppkandidater som anländer den 4 februari och 18 februari 2021. Produktionsutgåvan är planerad att publiceras 16 mars 2021.

Sjutton förslag riktar sig officiellt till JDK 16 från och med den 10 december 2020. De nya funktionerna som kommer till Java 16 inkluderar:

  • I varningarna för värdebaserade klassförslag anges de primitiva omslagsklasserna som värdebaserade och avskaffar deras konstruktörer för borttagning, vilket leder till nya varningar om avskrivning. Varningar ges om felaktiga försök att synkronisera i fall av värdebaserade klasser på Java-plattformen. Valhalla-projektet driver detta arbete, som strävar efter en betydande förbättring av Java-programmeringsmodellen i form av primitiva klasser. Primitiva klasser förklarar instanser som identitetsfria och kan integrerade eller planade representationer, där instanser kan kopieras fritt mellan minnesplatser och kodas med hjälp av värden i instansfält.Utformningen och implementeringen av primitiva klasser i Java är nu tillräckligt mogen för att migrering av vissa klasser av Java-plattformen till primitiva klasser kan förväntas i en framtida release. Kandidater för migration betecknas informellt som värdebaserade klasser i API-specifikationer.
  • Tidigare förhandsgranskad i JDK 15 begränsar förseglade klasser och gränssnitt vilka andra klasser och gränssnitt som kan förlänga eller implementera dem. Planens mål inkluderar att låta författaren till en klass eller ett gränssnitt styra koden som är ansvarig för att implementera den, tillhandahålla ett mer deklarativt sätt än åtkomstmodifierare för att begränsa användningen av en superklass och stödja framtida riktningar i mönstermatchning genom att ge en grund för analys av mönster.
  • Stark inkapsling av JDK-interner som standard, förutom kritiska interna API: er som misc.Unsafe. Användare kan välja den avslappnade starka inkapslingen som har varit standard sedan JDK 9. Målen i detta förslag inkluderar att förbättra JDK: s säkerhet och underhåll som en del av Project Jigsaw och uppmuntra utvecklare att migrera från att använda interna element till att använda standard-API: er att både utvecklare och slutanvändare enkelt kan uppdatera till framtida Java-utgåvor. Detta förslag medför en primär risk att befintlig Java-kod inte kan köras. Utvecklare uppmanas att använda jdeps-verktyget för att identifiera kod som beror på interna element i JDK och byta till standardersättningar när det är tillgängligt. Utvecklare kan använda en befintlig version, till exempel JDK 11, för att testa befintlig kod med hjälp av --illegal-access=warnför att identifiera interna element som nås via reflektion, använda för  --illegal-access=debugatt hitta felaktig kod och testa med --illegal-access=deny.
  • Utländskt länk-API, som erbjuder statiskt skriven, ren Java-åtkomst till inbyggd kod. Detta API kommer att befinna sig i ett inkubatorsteg i JDK 16. Tillsammans med det föreslagna främmande minnesåtkomst-API: et kommer den utländska länk-API: n att förenkla den annars felbenägna processen att binda till ett infödd bibliotek avsevärt. Denna plan är avsedd att ersätta JNI (Java Native Interface) med en överlägsen ren Java-utvecklingsmodell, för att erbjuda C-stöd och över tiden vara tillräckligt flexibel för att tillgodose stöd för andra plattformar, till exempel 32-bitars x86, och utländska funktioner skrivna på andra språk än C, till exempel C ++. Prestanda bör vara bättre än eller jämförbar med JNI.
  • Flytta ZGC (Z Garbage Collector) trådstapelbehandling från säkerhetspunkter till en samtidig fas. Målen för denna plan inkluderar att ta bort tråd-stack-bearbetning från ZGC-safepoäng; att göra stackbearbetning lat, samarbetsvillig, samtidigt och inkrementell; ta bort all annan rotbearbetning per tråd från ZGC-safepunkter; och tillhandahålla en mekanism för andra HotSpot VM-delsystem för att lata bearbeta stackar. ZGC är avsett att göra GC-pauser och skalbarhetsproblem i HotSpot till det förflutna. Hittills har GC-operationer som skalas med storleken på högen och storleken på metaspace flyttats ut ur safepoint-operationer och till samtidiga faser. Dessa har inkluderat markering, omplacering, referensbearbetning, klassavlastning och mest rotbearbetning.De enda aktiviteter som fortfarande görs i GC-safepoints är en delmängd av rotbearbetning och en tidsbegränsad markeringsavslutningsoperation. Dessa rötter har inkluderat Java-trådstackar och andra trådrötter, med dessa rötter är problematiska eftersom de skalas med antalet trådar. För att komma längre än den nuvarande situationen måste bearbetning per tråd, inklusive stack-skanning, flyttas till en samtidig fas. Med denna plan bör genomströmningskostnaden för den förbättrade latensen vara obetydlig och tiden i ZGC-säkerhetspunkter på typiska maskiner bör vara mindre än en millisekund.måste flyttas till en samtidig fas. Med denna plan bör genomströmningskostnaden för den förbättrade latensen vara obetydlig och tiden i ZGC-säkerhetspunkter på typiska maskiner bör vara mindre än en millisekund.måste flyttas till en samtidig fas. Med denna plan bör genomströmningskostnaden för den förbättrade latensen vara obetydlig och tiden i ZGC-säkerhetspunkter på typiska maskiner bör vara mindre än en millisekund.
  • En elastisk metaspace-funktion, som returnerar oanvänt HotSpot VM-klass metadata (metaspace) minne snabbare till operativsystemet, minskar metaspace footprint och förenklar metaspace-kod för att minska underhållskostnader. Metaspace har haft problem med hög minnesanvändning. Planen kräver ersättning av den befintliga minnesallokeraren med ett kompisbaserat allokeringsschema, vilket ger en algoritm för att dela upp minne i partitioner för att tillfredsställa minnesförfrågningar. Detta tillvägagångssätt har använts på platser som Linux-kärnan och kommer att göra det praktiskt att fördela minne i mindre bitar för att minska klassbelastningskostnader. Fragmentering kommer också att minskas. Dessutom kommer minnet från operativsystemet till minneshanteringsarenorna att göras lat, på begäran,för att minska fotavtrycket för lastare som börjar med stora arenor men som inte använder dem omedelbart eller kanske inte använder dem i sin fulla utsträckning. För att till fullo utnyttja den elasticitet som erbjuds av kompisallokering kommer metaspace-minne att ordnas i granuler i enhetligt storlek som kan kopplas in och kopplas oberoende av varandra.
  • Aktivering av C ++ 14-språkfunktioner för att möjliggöra användning av C ++ 14-funktioner i JDK C ++ källkod och ge specifik vägledning om vilka av dessa funktioner som kan användas i HotSpot VM-kod. Genom JDK 15 har språkfunktioner som används av C ++ - kod i JDK varit begränsade till C ++ 98/03 språkstandarder. Med JDK 11 uppdaterades källkoden för att stödja byggnad med nyare versioner av C ++ - standarden. Detta inkluderar att kunna bygga med senaste versioner av kompilatorer som stöder språkfunktioner i C ++ 11/14. Detta förslag föreslår inga ändringar av stil eller användning för C ++ - kod som används utanför HotSpot. Men för att dra nytta av C ++ - språkfunktioner krävs vissa byggtidsändringar beroende på plattformskompilatorn.
  • Ett vektor-API i ett inkubatorsteg, där JDK skulle utrustas med en inkubatormodul, jdk.incubator.vector, för att uttrycka vektorberäkningar som sammanställs till optimala vektorhårdvaruinstruktioner om CPU-arkitekturer som stöds, för att uppnå överlägsen prestanda till motsvarande skalära beräkningar. Vector API ger en mekanism för att skriva komplexa vektoralgoritmer i Java, med hjälp av befintligt stöd i HotSpot VM för vektorisering men med en användarmodell som gör vektorisering mer förutsägbar och robust. Förslagets mål inkluderar att tillhandahålla ett tydligt och koncist API för att uttrycka en rad vektorberäkningar, vara plattformsagnostiska genom att stödja flera CPU-arkitekturer och erbjuda pålitlig sammanställning och prestanda på x64- och AArch64-arkitekturer. Graciös nedbrytning är också ett mål,där en vektorberäkning skulle försämras elegant och fortfarande fungerar om den inte kan uttryckas fullständigt vid körning som en sekvens av hårdvaruvektorinstruktioner, antingen för att en arkitektur inte stöder vissa instruktioner eller någon annan CPU-arkitektur stöds inte.
  • Portera JDK till Windows / AArch64-plattformen. Med lanseringen av ny serverklass och konsument AArch64 (ARM64) hårdvara har Windows / AArch64 blivit en viktig plattform på grund av efterfrågan. Även om portningen i sig redan är mestadels komplett, fokuserar detta förslag på integrering av porten i huvudlinjen JDK-förvaret.
  • Portering av JDK till Alpine Linux och till andra Linux-distributioner som använder musl som sitt primära C-bibliotek, på x64- och AArch64-arkitekturer. Musl är en Linux-implementering av standardbibliotekets funktionalitet som beskrivs i ISO C- och Posix-standarderna. Alpine Linux används allmänt i molntjänster, mikrotjänster och behållarmiljöer på grund av dess lilla bildstorlek. En Docker-avbildning för Linux är mindre än 6 MB. Att låta Java köras direkt i sådana inställningar gör det möjligt för Tomcat, Jetty, Spring och andra populära ramar att arbeta i dessa miljöer. Genom att använda jlink för att minska storleken på Java-körtiden kan en användare skapa en ännu mindre bild som är skräddarsydd för att köra en specifik applikation.
  • Tillhandahålla registerklasser som fungerar som transparenta bärare för oföränderliga data. Rekord kan betraktas som nominella tuples. Rekord förhandsgranskades i JDK 14 och JDK 15. Denna ansträngning svarar på klagomål om att Java har varit för omfattande eller har för mycket ceremoni. Planens mål inkluderar att utforma en objektorienterad konstruktion som uttrycker en enkel aggregering av värden, hjälper utvecklare att fokusera på att modellera oföränderliga data snarare än utdragbart beteende, automatiskt implementera datadrivna metoder som equalsoch accessorer och bevara långvariga Java-principer som nominella skriver.
  • Tillägget av Unix-domän sockelkanaler, där Unix-domän (AF_UNIX) sockelstöd läggs till sockelkanalen och serveruttagskanal-API: er i paketet nio.channels. Planen utökar också den ärvda kanalmekanismen för att stödja Unix-domänuttagskanaler och serveruttagskanaler. Unix-domänuttag används för kommunikation mellan processer på samma värd. De liknar TCP / IP-uttag i de flesta avseenden förutom att de adresseras av filsystemets sökvägar snarare än IP-adresser och portnummer. Målet med den nya möjligheten är att stödja alla funktioner i Unix-domänuttagskanaler som är vanliga på stora Unix-plattformar och Windows. Unix-domän-uttagskanaler kommer att uppträda på samma sätt som befintliga TCP / IP-kanaler när det gäller läs- / skrivbeteende, anslutningsinställning, acceptans av inkommande anslutningar av servrar,och multiplexering med andra icke-blockerande valbara kanaler i en väljare. Unix-domänuttag är säkrare och effektivare än TCP / IP-loopback-anslutningar för lokal kommunikation mellan processer.
  • Ett åtkomst-API för främmande minne som gör att Java-program säkert kan komma åt främmande minne utanför Java-heapen. Tidigare inkuberades i både JDK 14 och JDK 15, skulle åtkomst-API för främmande minne återinkuberas i JDK 16 och lägga till förbättringar. Ändringar har gjorts inklusive en tydligare rollseparation mellan MemorySegmentoch MemoryAddressesgränssnitt. Målen med detta förslag är att tillhandahålla ett enda API för att fungera på olika typer av främmande minne, inklusive inbyggt, ihållande och hanterat högminne. API: et bör inte undergräva JVM: s säkerhet. Att motivera förslaget är att många Java-program får åtkomst till främmande minne, t.ex. Ignite, Memcached och MapDB. Men Java API ger inte en tillfredsställande lösning för åtkomst till främmande minne.
  • Mönstermatchning för instanceofoperatören, som också förhandsgranskades i både JDK 14 och JDK 15. Det skulle slutföras i JDK 16. Mönstermatchning tillåter gemensam logik i ett program, nämligen villkorlig utvinning av komponenter från objekt, att uttryckas mer kortfattat och säkert.
  • Tillhandahåller jpackage-verktyget för förpackning av fristående Java-applikationer. Introducerat som ett inkuberingsverktyg i JDK 14, förblev jpackage i inkubation i JDK 15. Med JDK 16 flyttar jpackage till produktion och stöder inbyggda paketformat för att ge användarna en naturlig installationsupplevelse och tillåta att starttidsparametrar specificeras vid förpackningstid. Formaten inkluderar msi och exe på Windows, pkg och dmg på MacOS, och deb och rpm på Linux. Verktyget kan åberopas direkt från kommandoraden eller programmatiskt. Det nya förpackningsverktyget adresserar en situation där många Java-applikationer måste installeras på inhemska plattformar på ett förstklassigt sätt snarare än att placeras på klassvägen eller modulvägen. Ett installerbart paket som är lämpligt för den inbyggda plattformen behövs.
  • Migrering av OpenJDK-källkodsförvar från Mercurial till Git. Att driva denna insats är fördelar med metadatastorlek för versionskontrollsystem och tillgängliga verktyg och värd.
  • Migration till GitHub, relaterad till Mercurial-to-Git-migrationen, med JDK 16-källkodsförvar för att vara på den populära koddelningswebbplatsen. JDK-funktionslanseringar och JDK-uppdateringsversioner för Java 11 och senare skulle vara en del av denna plan. Övergången till Git, GitHub och Skara för Mercurial JDK och JDK-sandlådan gjordes den 5 september och är öppen för bidrag.  

Tidiga åtkomstbyggnader av JDK 16 för Linux, Windows och MacOS finns på jdk.java.net. Liksom JDK 15 kommer JDK 16 att vara en kortvarig release, som stöds i sex månader. JDK 17, som förfaller i september 2021, kommer att vara en långvarig support (LTS) -release som kommer att få flera års stöd. Den nuvarande LTS-utgåvan, JDK 11, släpptes i september 2018.