JavaRush /Java blogi /Random-UZ /8 dan 13 gacha: Java versiyalarining to'liq ko'rinishi. 2...

8 dan 13 gacha: Java versiyalarining to'liq ko'rinishi. 2-qism

Guruhda nashr etilgan
Ushbu maqola mening Java 8-13 versiyalaridagi innovatsiyalarni ko'rib chiqishimning ikkinchi qismidir. Birinchi qism shu yerda . Ko'proq e'tibor bermasdan, keling: 2018 yil 25 sentyabrgacha, yangi JDK chiqarilganda:

Java 11

8 dan 13 gacha: Java versiyalarining to'liq ko'rinishi.  2-1-qism

var (lambdada)

Bundan buyon biz lambda parametrlarining turlarini belgilashimiz yoki lambda ifodasini yozishda ularni o'tkazib yuborishimiz mumkin (bevosita terilgan lambda ifodalari):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Oʻzgaruvchining toʻliq nomini yozmasdan ham lambda parametrlariga izoh qoʻshishingiz mumkin:
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

ZGC - bu ishlamaydigan yangi axlat yig'uvchi. U yangi xotira ajratadi, lekin uni hech qachon qayta ishga tushirmaydi. ZGC katta hajmdagi xotirani yuqori o'tkazuvchanlik va past kechikish bilan boshqarishni va'da qiladi (ZGC faqat 64 bitli platformalarda mavjud). Yo'naltiruvchi rang berish - ZGC 64-bitli ko'rsatkichlarni ko'rsatgichni ranglash deb ataladigan texnikadan foydalanadi. Rangli ko'rsatkichlar to'plamdagi ob'ektlar haqida qo'shimcha ma'lumotlarni saqlaydi. Xotira parchalanib ketganda, bu GC yangi ajratish uchun joy topishi kerak bo'lganda unumdorlikning pasayishini oldini olishga yordam beradi. ZGC yordamida axlat yig'ish quyidagi bosqichlardan iborat:
  1. dunyo to'xtash joylari: biz to'plamdagi ob'ektlarga (masalan, mahalliy o'zgaruvchilar yoki statik maydonlar) erishish uchun boshlang'ich nuqtalarni qidiramiz;
  2. ildiz bog'lanishlardan boshlanadigan ob'ekt grafiklarining kesishishi. Biz erishgan har bir ob'ektni belgilaymiz (ZGC ob'ekt grafigi bo'ylab yuradi va rangli markerlarni tekshiradi, mavjud ob'ektlarni belgilaydi);
  3. zaif havolalar kabi ba'zi chekka holatlar bilan ishlash;
  4. tirik ob'ektlarni ko'chirish, ajratishni tezlashtirish uchun uyumning katta maydonlarini bo'shatish.
  5. ko'chirish bosqichi boshlanganda, ZGC to'plamni sahifalarga ajratadi va bir vaqtning o'zida bir sahifa ishlaydi;
  6. ZGC har qanday ildizlarning harakatini tugatadi va harakatning qolgan qismi sodir bo'ladi.
Bu mavzu juda murakkab va chalkash. Batafsil muhokama qilish uchun alohida maqola kerak bo'ladi, shuning uchun men uni shu erda qoldiraman:

Epsilon GC

Epsilon - bu xotirani taqsimlash bilan shug'ullanadigan, lekin haqiqiy xotirani tiklash mexanizmini amalga oshirmaydigan axlat yig'uvchi. Mavjud Java to'plami tugagach, JVM o'chadi. Ya'ni, agar siz ushbu axlat yig'uvchi bilan mos yozuvlar bilan bog'lanmasdan cheksiz massivda ob'ekt yaratishni boshlasangiz, dastur OutOfMemoryError bilan ishlamay qoladi (va agar boshqasi bo'lsa, u ishlamay qoladi, chunki u ob'ektlarni havolalarsiz tozalaydi) . Nima uchun kerak? Buning sababi:
  1. Ishlash testi.
  2. Xotira bosimini tekshirish.
  3. VM interfeysi sinovdan o'tkazilmoqda.
  4. Juda qisqa ish.
  5. Oxirgi tushishning kechikishi yaxshilandi.
  6. Oxirgi pasayish tezligi yaxshilandi.
Foydali havolalar: Boshqa innovatsiyalar:
  1. ByteArrayOutputStreamvoid writeBytes(byte [])argumentdan barcha baytlarni yozadigan usulga ega bo'ldi OutputStream.
  2. FileReaderva FileWriterCharset ni belgilash imkonini beruvchi yangi konstruktorlar oldi.
  3. Pathikkita yangi usulni qo'lga kiritdi, string argumentidan birlashganda yo'l qatorini tashkil etuvchi yo'l yoki satrlar ketma-ketligini of(String, String [])qaytaradi va : URI dan Path ni qaytaradi.Pathof(URI)
  4. Pattern— berilgan kiritish satri berilgan naqshga mos kelishini tekshiradigan usul oldi asMatchPredicate()(masalan, oqimdagi maʼlumotlarni filtrlash uchun muntazam ifoda yordamida predikat yaratishga imkon beradimi yoki yoʻqmi).
  5. StringMen juda ko'p foydali usullarni tanladim, masalan:
    • String strip(): bizga ushbu satr bo'lgan satrni qaytaradi, satrning boshida va oxiridagi barcha bo'shliqlar olib tashlanadi (trim() ga o'xshash, lekin bo'shliqlarni boshqacha belgilaydi);
    • String stripLeading(): bizga ushbu satr bo'lgan satrni qaytaradi, satrdan oldingi bo'shliqlarni olib tashlaydi;
    • String stripTrailing(): satr oxiridagi barcha bo'shliqlarni olib tashlagan holda, bizga ushbu satr bo'lgan satrni qaytaradi;
    • Stream lines()Stream: bizni dan qaytaradi String, bu qatordan ajratilgan, qator ajratgichlar bilan ajratilgan;
    • String repeat(int): bizga bir necha marta takrorlangan ushbu satrning birikmasi bo'lgan qatorni qaytaradi.
    • boolean isBlank(): agar satr bo'sh bo'lsa yoki faqat bo'sh joy bo'lsa, true qiymatini qaytaradi, aks holda false.
  6. Thread— destroy() va stop(Throwable) usullari olib tashlandi.
  7. Filesbir qator yangi usullar mavjud:
    • String readString(Path): UTF-8 kodlash yordamida baytlardan belgilargacha dekodlashda fayldan barcha ma'lumotlarni satrga o'qiydi;
    • String readString(Path, Charset): yuqoridagi usulda bo'lgani kabi, baytlardan belgilarga dekodlash belgilangan Charset yordamida amalga oshiriladigan farq bilan;
    • Path writeString (Path, CharSequence, OpenOption []): Faylga belgilar ketma-ketligini yozadi. Belgilar UTF-8 kodlash yordamida baytlarga kodlangan;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Yuqoridagi usul bilan bir xil, faqat belgilar Charsetda ko'rsatilgan kodlash yordamida baytlarga kodlanadi.
Bu eng qiziqarli API yangiliklari edi (mening kamtarona fikrimcha), bu erda batafsilroq ko'rib chiqish uchun bir nechta materiallar mavjud:

Java 12

Olti oy o'tadi va biz Java evolyutsiyasining keyingi bosqichini ko'ramiz. Shunday qilib, bilim belkurakini olib, qazish vaqti keldi. 8 dan 13 gacha: Java versiyalarining to'liq ko'rinishi.  2-2 qism

G1-ni yangilang

G1 uchun quyidagi yaxshilanishlar kiritildi:
  1. Ishlatilmagan ajratilgan xotirani tiklang

    Java yig'ma xotirasida foydalanilmagan xotira (yoki boshqacha aytganda, faol emas) kabi narsa mavjud. Java 12 da ular ushbu muammoni hal qilishga qaror qilishdi, endi:

    • G1 xotirani to'liq GCda yoki parallel sikl davomida to'pdan qaytaradi; G1 to'liq GC ni oldini olishga harakat qiladi va yig'ish taqsimotiga asoslangan parallel tsiklni boshlaydi. Biz G1 ni xotirani yig'ishdan qaytarishga majbur qilishimiz kerak.

    Ushbu takomillashtirish G1 ishlatilmayotganda xotirani yig'ishdan OTga avtomatik ravishda qaytarish orqali ishlashga qaratilgan.

  2. Pauza vaqti oshib ketganda aralash kollektsiyalarni bekor qilish

    G1 axlat yig'ish uchun zarur bo'lgan ish hajmini tanlash uchun tahlil mexanizmidan foydalanadi. U to'plamni belgilab, tozalashni boshlagandan so'ng to'xtamasdan jonli ob'ektlarni to'playdi. Bu axlat yig'uvchining pauza vaqtidan oshib ketishiga olib keladi. Aslida, bu muammoni takomillashtirish orqali hal qilinadi, chunki keyingi bosqichni bajarish uchun zarur bo'lgan vaqt oqilona chegaralardan tashqarida bo'lsa, bu qadam to'xtatilishi mumkin.

Mikrobenchmark

Java 12 mikrobenchmarking testlarini joriy qildi, shunda JVM ish faoliyatini mavjud ko'rsatkichlar yordamida osongina sinab ko'rish mumkin. Bu JVM ning o'zida ishlashni istagan har bir kishi uchun juda foydali bo'ladi. Qo'shilgan testlar Java Microbenchmark Harness (JMH) yordamida yaratilgan. Ushbu testlar JVMda uzluksiz ishlash testlarini o'tkazish imkonini beradi. JEP 230 100 ga yaqin testlarni joriy etishni taklif qiladi, Java-ning yangi versiyalari chiqarilganda yangi testlar kiritiladi. Bu erda qo'shilayotgan testlarga misol .

Shenandoah

Bu axlat yig'ish (GC) algoritmi bo'lib, uning maqsadi past javob vaqtlarini kafolatlashdir (pastki chegara 10-500 ms). Bu Java iplarini ishga tushirish bilan bir vaqtda tozalash ishlarini bajarishda GC pauza vaqtini qisqartiradi. Shenandoahda pauza vaqti to'p hajmiga bog'liq emas. Bu sizning to'plamingiz hajmidan qat'i nazar, pauza vaqti bir xil bo'lishini anglatadi. Bu eksperimental xususiyatdir va OpenJDK standart (Oracle) tuzilishiga kiritilmagan.

Switch-ni yaxshilash

Java 12 naqshni moslashtirish uchun Switch ifodalarini yaxshilagan. Yangi L → sintaksisi kiritildi. Mana yangi kalitning asosiy nuqtalari ro'yxati :
  1. Yangi sintaksis xatolarning oldini olish uchun break bayonotiga ehtiyojni yo'q qiladi.
  2. Ifodalarni almashtirish endi muvaffaqiyatsiz tugadi.
  3. Bundan tashqari, biz bitta yorliqda bir nechta konstantalarni belgilashimiz mumkin.
  4. kommutator iboralarida endi standart holat talab qilinadi.
  5. break registrning o'zidan qiymatlarni qaytarish uchun Switch iboralarida ishlatiladi (aslida kalit qiymatlarni qaytarishi mumkin).
Keling, buni misol sifatida ko'rib chiqaylik:
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
            break "Please insert a valid day.";
      else
            break "Looks like a Sunday.";
  }
};
Java 13 da ifodalarni almashtirish bo'yicha aniq qo'llanma Boshqa yangi xususiyatlar:
  1. String:

    transform(Function f)- Taqdim etilgan funktsiyani satrga qo'llaydi. Natija qator bo'lmasligi mumkin.
    indent(int x)— satrga x boʻsh joy qoʻshadi. Agar parametr salbiy bo'lsa, unda bu etakchi bo'shliqlar soni o'chiriladi (agar iloji bo'lsa).

  2. Files- kabi usulni qo'lga kiritdi mismatch(), bu esa o'z navbatida ikkita fayl mazmunidagi birinchi mos kelmaydigan baytning o'rnini topadi va qaytaradi yoki mos kelmaydigan bo'lsa -1L.

  3. Yangi sinf paydo bo'ldi -CompactNumberFormat o'nlik sonni ixcham shaklda formatlash uchun. Ushbu ixcham shaklga misol 1 000 000 o'rniga 1M. Shunday qilib, to'qqizta belgi o'rniga faqat ikkita ikkita belgi talab qilinadi.

  4. Shuningdek , ikkita qiymatga ega bo'lgan yangisi mavjud - UZOQ va QISQA.enumNumberFormatStyle

  5. InputStream usulni oldi skipNBytes(long n) : kirish oqimidan baytlarning n-sonini o'tkazib yuboring.

Qiziqarli Java 12 havolalari:

Java 13

Dunyo xuddi Java - Java 13 kabi bir joyda turmaydi, harakat qiladi, rivojlanadi. 8 dan 13 gacha: Java versiyalarining to'liq ko'rinishi.  2-3 qism

Matn bloki

Java har doim satrlarni belgilashda biroz azob chekdi. Agar qatorni boʻsh joy, qator uzilishi, tirnoq yoki boshqa biror narsa bilan belgilashimiz kerak boʻlsa, bu baʼzi qiyinchiliklarga sabab boʻldi, shuning uchun biz maxsus belgilardan foydalanishga majbur boʻldik: masalan, qator uzilishi uchun \n yoki qatorning bir qismidan qochishimiz kerak edi. o'zi. Bu kodning o'qilishini sezilarli darajada kamaytiradi va bunday qatorni yozishda qo'shimcha vaqt talab etiladi. Bu JSON, XML, HTML va hokazolarni aks ettiruvchi satrlarni yozishda ayniqsa seziladi. Natijada, agar biz kichik Json yozmoqchi bo'lsak, u quyidagicha ko'rinadi:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
Va keyin Java 13 sahnaga chiqadi va bizga matndan oldin va keyin (ular matn bloklari deb atalgan) uch qo'sh tirnoq shaklida o'z yechimini taklif qiladi. Keling, ushbu yangilikdan foydalangan holda oldingi json misolini ko'rib chiqaylik:
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
Bu ancha sodda va tushunarli, shunday emasmi? StringUshbu bloklarni boshqarish uchun mos ravishda uchta yangi usul qo'shildi :
  • stripIndent(): Satrdan tasodifiy bo'shliqlarni olib tashlaydi. Agar siz ko'p qatorli satrlarni o'qiyotgan bo'lsangiz va aniq deklaratsiya bilan yuzaga keladigan bir xil turdagi tasodifiy bo'shliqni istisno qilishni xohlasangiz foydali bo'ladi (asosan tasodifiy bo'shliqni olib tashlash uchun kompilyatorni simulyatsiya qilish);
  • formatted(Object... args ): ga o'xshash format(String format, Object... arg), lekin matn bloklari uchun;
  • translateEscapes(): Tegishli Unicode qiymatiga tarjima qilingan qochish ketma-ketliklari (masalan, \r) bilan satrni qaytaradi.

Switch-ni yaxshilash

Switch iboralari Java 12 da joriy qilingan va 13 tasi ularni yaxshilaydi. 12-da siz qaytish qiymatlarini break yordamida aniqlaysiz. 13-da, qaytarish qiymati rentabellik bilan almashtirildi. Endi Java 12 bo'limida mavjud bo'lgan switch ifodasi quyidagicha qayta yozilishi mumkin:
var result = switch (someDay) {
  case "M", "W", "F" -> "MWF";
  case "T", "TH", "S" -> "TTS";
  default -> {
      if(someDay.isEmpty())
          yield "Please insert a valid day.";
      else
          yield "Looks like a Sunday.";
  }
};
Biz Java-ni yaxshi bilgan dasturchilar uchun tanaffusni qabul qilish odatiy hol bo'lsa-da, bu juda g'alati edi. Menga aytmoqchi bo'lgan haqiqat nima? Yangi (nisbatan yangi) yield kalit so'zi aniqroq va kelajakda qiymatlar qaytariladigan boshqa joylarda paydo bo'lishi mumkin. Ushbu mavzuga chuqur qiziqqanlar uchun men sizga ushbu materiallar bilan tanishishingizni tavsiya qilaman:

Dinamik CDS arxivlari

CDS - sinf ma'lumotlarini almashish. Tez-tez ishlatiladigan sinflar to'plamini keyinchalik bir nechta JVM nusxalari tomonidan yuklanishi mumkin bo'lgan arxivga joylashtirish imkonini beradi. Nega bizga bu kerak? Gap shundaki, sinflarni yuklash jarayonida JVM juda ko'p resurs talab qiladigan harakatlarni amalga oshiradi, masalan, darslarni o'qish, ularni ichki tuzilmalarda saqlash, o'qilgan sinflarning to'g'riligini tekshirish, qaram sinflarni qidirish va yuklash va h.k. ., va shundan keyingina darslar ishlashga tayyor. JVM nusxalari ko'pincha bir xil sinflarni yuklashi mumkinligi sababli, ko'p resurslar isrof bo'lishi tushunarli. Masalan, String, LinkedList, Integer. Xo'sh, yoki bir xil dasturning sinflari va bularning barchasi resurslardir. Agar biz barcha kerakli amallarni bir marta bajargan bo'lsak va keyin qayta ishlangan sinflarni bir nechta JVM xotirasiga yuklanishi mumkin bo'lgan arxivga joylashtirsak, bu xotira maydonini sezilarli darajada tejash va ilovalarni ishga tushirish vaqtini qisqartirishi mumkin. Aslida, CDS aynan shunday arxivni yaratishga imkon beradi. Java 9 faqat tizim sinflarini arxivga qo'shishga ruxsat berdi. Java 10 - arxivga dastur sinflarini kiritish. Bunday arxivni yaratish quyidagilardan iborat:
  • ilova tomonidan yuklangan sinflar ro'yxatini yaratish;
  • topilgan sinflar bilan juda kerakli arxiv yaratish.
Java 13-dagi yangilik CDS-ni yaxshilaydi, shuning uchun dastur tugashi bilan arxiv yaratishi mumkin. Bu shuni anglatadiki, yuqoridagi ikkita qadam endi bittaga birlashtiriladi. Va yana bir muhim jihat: faqat dastur ishlayotgan vaqtda yuklangan sinflar arxivga qo'shiladi. Boshqacha qilib aytadigan bo'lsak, hali ham application.jar da mavjud bo'lgan, lekin biron sababga ko'ra yuklanmagan sinflar arxivga qo'shilmaydi.

Socket API-ni yangilang

Socket API ( java.net.Socket va java.net.ServerSocket ) mohiyatan Java tilining yaratilganidan beri ajralmas qismi hisoblanadi, biroq soketlar oxirgi yigirma yil ichida hech qachon yangilanmagan. C va Java tillarida yozilgan, ular juda, juda katta hajmli va ularga xizmat ko'rsatish qiyin edi. Ammo Java 13 bu masalaga o'z tuzatishlarini kiritishga qaror qildi va asosiy dasturni almashtirdi. Endi PlainSocketImpl o'rniga provayder interfeysi NioSocketImpl bilan almashtirildi . Ushbu yangi kodlangan dastur java.nio bilan bir xil back-end infratuzilmasiga asoslangan . Asosan, sinf sinxronlashtirilgan usullardan ko'ra java.util.concurrent bufer keshini va qulflash mexanizmidan (segmentga asoslangan) foydalanadi. U endi mahalliy kodni talab qilmaydi, bu esa turli platformalarga portlashni osonlashtiradi. Shunga qaramay, bizda PlainSocketImpl dan foydalanishga qaytishning yo'li bor , ammo bundan buyon NioSocketImpl sukut bo'yicha ishlatiladi .

ZGC uchun xotirani qaytarish

Esingizda bo'lsa, Z axlat yig'uvchisi Java 11-da GC pauzasi hech qachon 10 ms dan oshmasligi uchun past kechikishli axlat yig'ish mexanizmi sifatida taqdim etilgan. Biroq, shu bilan birga, Shenandoah va G1 kabi boshqa virtual GC Hotspots-dan farqli o'laroq, u foydalanilmagan dinamik xotirani OTga qaytarishi mumkin. Ushbu modifikatsiya ushbu J qobiliyatini ZGC-ga qo'shadi. Shunga ko'ra, biz yaxshilangan ishlash bilan birga qisqargan xotira maydoniga ega bo'lamiz va ZGC endi belgilangan minimal yig'ish hajmiga yetguncha sukut bo'yicha operatsion tizimga sozlanmagan xotirani qaytaradi. Yana bir narsa: ZGC endi maksimal qo'llab-quvvatlanadigan yig'ma hajmi 16 TB. Ilgari 4TB chegara edi. Boshqa innovatsiyalar:
  1. javax.securityjdk.sasl.disabledMechanisms- SASL mexanizmlarini o'chirish uchun xususiyat qo'shildi .
  2. java.nioFileSystems.newFileSystem (Path, Map <String,?>)- mos ravishda yangi fayl yaratish usuli qo'shildi .
  3. Sinflar java.nioendi mutlaq (nisbiydan farqli o'laroq) getva set-metodlarga ega. Ular, asosiy abstrakt sinf kabi , buferning bir qismini olish Bufferusulini o'z ichiga oladi .slice()
  4. DOM va SAX zavodlarini yaratish uchun qo'shilgan javax.xml.parsersusullar (nomlar maydonini qo'llab-quvvatlash bilan).
  5. Unicode qo'llab-quvvatlashi 12.1 versiyasiga yangilandi.
Java 13 bo'yicha qiziqarli havolalar:

Natijalar

Biz Java 14-da e'lon qilingan yangiliklarni ko'rib chiqishimiz mumkin edi, ammo u tez orada yorug'likni ko'radi - JDK 14 2020 yil 17 martda chiqarilishi rejalashtirilganligi sababli, uni chiqarilgandan so'ng darhol alohida, to'liq ko'rib chiqish yaxshi bo'lar edi. . Shuningdek, e'tiboringizni Python 2–3 kabi relizlar o'rtasida uzoq tanaffuslarga ega bo'lgan boshqa dasturlash tillarida moslik yo'qligiga qaratmoqchiman: ya'ni agar kod Python 2 da yozilgan bo'lsa, siz uni 3 ga tarjima qilish uchun qattiq ishlash kerak. Java bu borada alohida ahamiyatga ega, chunki u juda orqaga mos keladi. Bu shuni anglatadiki, sizning Java 5 yoki 8 dasturingiz Java 8-13 virtual mashinasida ishlashi kafolatlangan - hozircha tashvishlanishingizga hojat yo'q bir nechta istisnolar. Bu teskari ishlamasligi aniq: masalan, ilovangiz Java 8 JVM-da mavjud bo'lmagan Java 13 funksiyalaridan foydalansa. Bugun menda bor narsa shu, shu paytgacha o'qiganlarga hurmat)) 8 dan 13 gacha: Java versiyalarining to'liq ko'rinishi.  2-5 qism
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION