JavaRush /Java Blog /Random-TL /Mula 8 hanggang 13: isang kumpletong pangkalahatang-ideya...

Mula 8 hanggang 13: isang kumpletong pangkalahatang-ideya ng mga bersyon ng Java. Bahagi 2

Nai-publish sa grupo
Ang artikulong ito ay ang pangalawang bahagi ng aking pagsusuri ng mga inobasyon sa Java na bersyon 8-13. Ang unang bahagi ay narito . Nang walang karagdagang abala, magpatuloy tayo: hanggang Setyembre 25, 2018, nang ilabas ang bagong JDK:

Java 11

Mula 8 hanggang 13: isang kumpletong pangkalahatang-ideya ng mga bersyon ng Java.  Bahagi 2 - 1

var (sa lambda)

Mula ngayon, maaari naming tukuyin ang mga uri ng mga parameter ng lambda o tanggalin ang mga ito kapag nagsusulat ng isang lambda na expression (implicitly na na-type na mga lambda expression):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Maaari ka ring magdagdag ng mga anotasyon sa mga parameter ng lambda nang hindi kinakailangang isulat ang buong pangalan ng uri ng variable:
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

Ang ZGC ay isang bagong basurero na hindi gumagana. Naglalaan ito ng bagong memorya ngunit hindi na ito muling na-restart. Nangangako ang ZGC na pamahalaan ang malaking halaga ng memory na may mataas na throughput at mababang latency (magagamit lamang ang ZGC sa 64-bit na mga platform). Pangkulay ng Sanggunian - Gumagamit ang ZGC ng 64-bit na mga pointer na may pamamaraan na tinatawag na pointer coloring. Ang mga may kulay na pointer ay nag-iimbak ng karagdagang impormasyon tungkol sa mga bagay sa heap. Kapag nagkapira-piraso ang memorya, nakakatulong itong maiwasan ang pagkasira ng performance kapag kailangan ng GC na maghanap ng puwang para sa isang bagong alokasyon. Ang pangongolekta ng basura gamit ang ZGC ay binubuo ng mga sumusunod na hakbang:
  1. paghinto ng mundo: naghahanap kami ng mga panimulang punto upang maabot ang mga bagay sa heap (tulad ng mga lokal na variable o static na field);
  2. intersection ng mga object graph na nagsisimula sa root links. Minarkahan namin ang bawat bagay na naabot namin (naglalakad ang ZGC sa object graph at sinusuri ang mga may kulay na pointer, na nagmamarka ng mga magagamit na bagay);
  3. paghawak ng ilang mga gilid na kaso, tulad ng mga mahihinang link;
  4. paglipat ng mga live na bagay, pagpapalaya sa malalaking lugar ng bunton upang mapabilis ang paglalaan.
  5. kapag nagsimula ang yugto ng paglipat, hinahati ng ZGC ang heap sa mga pahina at gumagana nang paisa-isa;
  6. Tinatapos ng ZGC ang paggalaw ng anumang mga ugat at ang natitirang paggalaw ay nangyayari.
Napakasalimuot at nakakalito ang paksang ito. Ang isang detalyadong talakayan ay mangangailangan ng isang hiwalay na artikulo, kaya iiwan ko lang ito dito:

Epsilon GC

Ang Epsilon ay isang garbage collector na humahawak ng memory allocation ngunit hindi nagpapatupad ng anumang tunay na memory recovery mechanism. Kapag naubos na ang available na Java heap, magsasara ang JVM. Iyon ay, kung magsisimula kang lumikha ng isang bagay sa isang walang katapusang hanay nang hindi nagbubuklod sa isang sanggunian sa kolektor ng basura na ito, ang application ay mag-crash sa isang OutOfMemoryError (at kung sa anumang iba pa, hindi ito gagawin, dahil lilinisin nito ang mga bagay nang walang mga sanggunian) . Bakit kailangan ito? Narito kung bakit:
  1. Subukan ang performance.
  2. Pagsubok sa presyon ng memorya.
  3. Pagsubok sa interface ng VM.
  4. Napakaikling gawain.
  5. Mga pagpapahusay sa latency ng huling pagbaba.
  6. Huling pagbaba ng throughput na mga pagpapabuti.
Mga kapaki-pakinabang na link: Iba pang mga inobasyon:
  1. ByteArrayOutputStreamnakakuha ng isang pamamaraan void writeBytes(byte [])na nagsusulat ng lahat ng mga byte mula sa argumento hanggang sa OutputStream.
  2. FileReaderat FileWriternakakuha ng mga bagong konstruktor na nagpapahintulot sa iyo na tukuyin ang Charset.
  3. Pathgrabbed dalawang bagong pamamaraan, of(String, String [])nagbabalik Pathmula sa isang string argument ng isang path o sequence ng mga string na kapag pinagsama ay bumubuo ng isang path string at of(URI): nagbabalik ng Path mula sa isang URI.
  4. Pattern— nakatanggap ng isang paraan asMatchPredicate()na nagsusuri kung ang isang ibinigay na input string ay tumutugma sa isang ibinigay na pattern (kung ito ay nagpapahintulot sa iyo na lumikha ng isang predicate gamit ang isang regular na expression upang maaari mong, halimbawa, i-filter ang data sa stream).
  5. StringNakakuha ako ng maraming kapaki-pakinabang na pamamaraan, tulad ng:
    • String strip(): ay magbabalik sa amin ng isang string na ang string na ito, na ang lahat ng mga puwang sa simula at dulo ng string ay tinanggal (katulad ng trim(), ngunit tumutukoy sa mga puwang sa ibang paraan);
    • String stripLeading(): ibabalik sa amin ang string na ito na string, na nag-aalis ng anumang mga nangungunang puwang mula sa string;
    • String stripTrailing(): ibabalik sa amin ang string na ito na string, na nag-aalis ng anumang mga puwang sa dulo ng string;
    • Stream lines(): ay magbabalik sa amin Streammula sa String, kinuha mula sa string na ito, na pinaghihiwalay ng mga line separator;
    • String repeat(int): ay magbabalik sa amin ng isang string na pinagsama-sama ng string na ito, na paulit-ulit nang ilang beses.
    • boolean isBlank(): ay magbabalik ng true kung ang string ay walang laman o naglalaman lamang ng mga puwang, false kung hindi.
  6. Thread— ang mga paraan ng destroy() at stop(Throwable) ay inalis na.
  7. Filesnakakuha ng ilang mga bagong pamamaraan:
    • String readString(Path): binabasa ang lahat ng data mula sa isang file patungo sa isang string, habang nagde-decode mula sa mga byte patungo sa mga character gamit ang UTF-8 encoding;
    • String readString(Path, Charset): katulad ng sa pamamaraan sa itaas, na may pagkakaiba na ang pag-decode mula sa mga byte hanggang sa mga character ay nangyayari gamit ang tinukoy na Charset;
    • Path writeString (Path, CharSequence, OpenOption []): Nagsusulat ng pagkakasunod-sunod ng mga character sa isang file. Ang mga character ay naka-encode sa mga byte gamit ang UTF-8 encoding;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Parehong paraan tulad ng nasa itaas, ang mga character lamang ang naka-encode sa mga byte gamit ang pag-encode na tinukoy sa Charset.
Ito ang pinakakawili-wiling mga inobasyon ng API (sa aking mapagpakumbabang opinyon), narito ang ilang materyales para sa mas detalyadong pagsusuri:

Java 12

Lumipas ang anim na buwan at nakita natin ang susunod na yugto sa ebolusyon ng Java. Kaya, oras na upang kunin ang pala ng kaalaman at maghukay. Mula 8 hanggang 13: isang kumpletong pangkalahatang-ideya ng mga bersyon ng Java.  Bahagi 2 - 2

I-update ang G1

Ang mga sumusunod na pagpapabuti ay ginawa para sa G1:
  1. I-reclaim ang hindi nagamit na inilaan na memorya

    Sa Java heap memory mayroong isang bagay tulad ng hindi nagamit na memorya (o sa madaling salita, hindi aktibo). Sa Java 12 nagpasya silang ayusin ang problemang ito, ngayon:

    • Ang G1 ay nagbabalik ng memorya mula sa heap sa isang buong GC o sa isang parallel loop; Sinusubukan ng G1 na pigilan ang isang buong GC at sinimulan ang isang parallel loop batay sa paglalaan ng heap. Kakailanganin nating pilitin ang G1 na ibalik ang memorya mula sa heap.

    Nakatuon ang pagpapahusay na ito sa pagganap sa pamamagitan ng awtomatikong pagbabalik ng memorya mula sa heap patungo sa OS kapag hindi ginagamit ang G1.

  2. Ipinaabort ang mga pinaghalong koleksyon kapag nalampasan na ang oras ng pag-pause

    Gumagamit ang G1 ng analysis engine para piliin ang dami ng trabahong kailangan para sa pangongolekta ng basura. Nangongolekta ito ng mga live na bagay nang walang tigil pagkatapos tukuyin ang set at simulan ang paglilinis. Nagiging sanhi ito ng basurero na lumampas sa target ng oras ng pag-pause nito. Sa totoo lang, ang problemang ito ay nalutas sa pamamagitan ng pagpapabuti, dahil kung ang oras ng pagpapatupad ng susunod na hakbang ay lampas sa makatwirang limitasyon, ang hakbang na ito ay maaaring maantala.

Microbenchmark

Ipinakilala ng Java 12 ang mga pagsubok sa microbenchmarking upang ang pagganap ng JVM ay madaling masuri gamit ang mga kasalukuyang benchmark. Ito ay magiging lubhang kapaki-pakinabang para sa sinumang gustong magtrabaho sa JVM mismo. Ang mga idinagdag na pagsubok ay nilikha gamit ang Java Microbenchmark Harness (JMH). Ang mga pagsubok na ito ay nagbibigay-daan para sa patuloy na pagsubok sa pagganap sa JVM. Ang JEP 230 ay nagmumungkahi ng pagpapakilala ng humigit-kumulang 100 mga pagsubok, na may mga bagong pagsubok na ipinakilala habang ang mga bagong bersyon ng Java ay inilabas. Narito ang isang halimbawa ng mga pagsubok na idinaragdag .

Shenandoah

Isa itong algorithm ng pangongolekta ng basura (GC) na ang layunin ay garantiyahan ang mababang oras ng pagtugon (ang mas mababang limitasyon ay 10-500 ms). Binabawasan nito ang oras ng pag-pause ng GC kapag gumagawa ng paglilinis nang sabay-sabay sa pagpapatakbo ng mga Java thread. Sa Shenandoah, ang oras ng pag-pause ay hindi nakasalalay sa laki ng heap. Nangangahulugan ito na ang oras ng pag-pause ay magiging pareho anuman ang laki ng iyong heap. Isa itong feature na pang-eksperimento at hindi kasama sa standard (Oracle) build ng OpenJDK.

Pagbutihin ang Switch

Pinahusay ng Java 12 ang mga expression ng Switch para sa pagtutugma ng pattern. Isang bagong syntax L → ang ipinakilala. Narito ang isang listahan ng mga pangunahing punto ng bagong switch :
  1. Ang bagong syntax ay nag-aalis ng pangangailangan para sa isang break na pahayag upang maiwasan ang mga error.
  2. Hindi na nabigo ang paglipat ng mga expression.
  3. Bilang karagdagan, maaari naming tukuyin ang maramihang mga constant sa iisang label.
  4. kailangan na ngayon ng default na case sa mga switch expression.
  5. Ang break ay ginagamit sa mga expression ng Switch upang ibalik ang mga halaga mula sa rehistro mismo (sa katunayan, ang isang switch ay maaaring magbalik ng mga halaga).
Tingnan natin ito bilang isang halimbawa:
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.";
  }
};
Depinitibong Gabay Upang Magpalit ng mga Ekspresyon Sa Java 13 Iba pang mga bagong tampok:
  1. String:

    transform(Function f)- Inilalapat ang ibinigay na function sa isang string. Ang resulta ay maaaring hindi isang string.
    indent(int x)- nagdaragdag ng mga x space sa string. Kung negatibo ang parameter, aalisin ang bilang ng mga nangungunang puwang na ito (kung maaari).

  2. Files- kumuha ng paraan tulad mismatch()ng , na, sa turn, ay hinahanap at ibinabalik ang posisyon ng unang hindi tugmang byte sa mga nilalaman ng dalawang file, o -1L kung walang mismatch.

  3. Ang isang bagong klase ay lumitaw -CompactNumberFormat para sa pag-format ng isang decimal na numero sa isang compact form. Ang isang halimbawa ng compact form na ito ay 1M sa halip na 1,000,000. Kaya, dalawang dalawa lang ang kinakailangan sa halip na siyam na character.

  4. Mayroon ding bago enum , NumberFormatStylena may dalawang halaga - MAHABA at MAIKLING.

  5. InputStream nakuha ang pamamaraan skipNBytes(long n) : laktawan ang ika-n na bilang ng mga byte mula sa input stream.

Mga kawili-wiling link ng Java 12:

Java 13

Ang mundo ay hindi tumitigil, ito ay gumagalaw, ito ay umuunlad, tulad ng Java - Java 13. Mula 8 hanggang 13: isang kumpletong pangkalahatang-ideya ng mga bersyon ng Java.  Bahagi 2 - 3

Text block

Ang Java ay palaging nagdusa nang kaunti pagdating sa pagtukoy ng mga string. Kung kailangan naming tukuyin ang isang linya na may puwang, isang line break, isang quote o iba pa, nagdulot ito ng ilang mga paghihirap, kaya kailangan naming gumamit ng mga espesyal na character: halimbawa, \n para sa isang line break, o tumakas sa ilang linya mismo. Ito ay makabuluhang binabawasan ang pagiging madaling mabasa ng code at tumatagal ng dagdag na oras kapag nagsusulat ng ganoong linya. Lalo itong nagiging kapansin-pansin kapag nagsusulat ng mga string na nagpapakita ng JSON, XML, HTML, atbp. Bilang resulta, kung gusto naming magsulat ng isang maliit na Json, magiging ganito ang hitsura:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
At pagkatapos ay dumating ang Java 13 sa eksena at nag-aalok sa amin ng solusyon nito sa anyo ng triple double quote bago at pagkatapos ng teksto (na tinawag nilang mga bloke ng teksto). Tingnan natin ang nakaraang halimbawa ng json gamit ang pagbabagong ito:
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
Mas simple at mas malinaw, hindi ba? StringTatlong bagong pamamaraan din ang idinagdag, ayon sa pagkakabanggit, para sa pamamahala sa mga bloke na ito:
  • stripIndent(): Tinatanggal ang mga random na espasyo mula sa isang string. Ito ay kapaki-pakinabang kung nagbabasa ka ng mga multiline na string at gusto mong ilapat ang parehong uri ng random na pagbubukod ng whitespace na nangyayari sa isang tahasang deklarasyon (pangunahing ginagaya ang compiler upang alisin ang random na whitespace);
  • formatted(Object... args ): katulad ng format(String format, Object... arg), ngunit para sa mga bloke ng teksto;
  • translateEscapes(): Nagbabalik ng string na may mga escape sequence (gaya ng \r) na isinalin sa katumbas na halaga ng Unicode.

Pagbutihin ang Switch

Ang mga expression ng switch ay ipinakilala sa Java 12, at 13 ay pinipino ang mga ito. Sa 12, tinukoy mo ang mga halaga ng pagbabalik gamit ang break. Sa 13, ang return value ay pinalitan ng yield. Ngayon ang switch expression na mayroon kami sa Java 12 na seksyon ay maaaring muling isulat bilang:
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.";
  }
};
Bagama't normal para sa amin na mga programmer na pamilyar sa Java ang tumanggap ng pahinga, gayunpaman ay medyo kakaiba. Ano ang sinusubukang sabihin sa akin ng break true? Ang bagong (medyo bago) yield na keyword ay mas malinaw at maaaring lumitaw sa ibang mga lugar sa hinaharap kung saan ibinalik ang mga halaga. Para sa mga labis na interesado sa paksang ito, inirerekumenda kong pamilyar ka sa mga materyal na ito:

Mga Dynamic na CDS Archive

CDS - Class-Data Sharing. Binibigyang-daan kang mag-package ng isang hanay ng mga karaniwang ginagamit na klase sa isang archive na maaaring i-load sa ibang pagkakataon ng maraming mga JVM instance. Bakit kailangan natin ang mga ito? Ang katotohanan ay na sa proseso ng paglo-load ng mga klase, ang JVM ay gumagawa ng napakaraming mga aksyon na masinsinang mapagkukunan, tulad ng mga klase sa pagbabasa, pag-iimbak ng mga ito sa mga panloob na istruktura, pagsuri sa kawastuhan ng mga klase sa pagbasa, paghahanap at pag-load ng mga umaasa na klase, atbp. ., at pagkatapos lamang ng lahat ng ito ang mga klase ay handa nang magtrabaho. Mauunawaan, maraming mga mapagkukunan ang nasasayang, dahil ang mga pagkakataon ng JVM ay madalas na naglo-load ng parehong mga klase. Halimbawa String, LinkedList, Integer. Well, o mga klase ng parehong aplikasyon, at lahat ng ito ay mga mapagkukunan. Kung ginawa namin ang lahat ng kinakailangang hakbang nang isang beses lamang at pagkatapos ay inilagay ang mga muling idinisenyong klase sa isang archive na maaaring i-load sa memorya ng ilang JVM, maaari itong makabuluhang makatipid ng espasyo sa memorya at mabawasan ang oras ng pagsisimula ng application. Sa totoo lang, ginagawang posible ng CDS na lumikha ng ganoong archive. Pinapayagan lamang ng Java 9 ang mga klase ng system na idagdag sa archive. Java 10 - isama ang mga klase ng application sa archive. Ang paglikha ng naturang archive ay binubuo ng:
  • paglikha ng isang listahan ng mga klase na na-load ng application;
  • paglikha ng isang kailangang-kailangan na archive kasama ang mga klase na nakita namin.
Pinapabuti ng inobasyon sa Java 13 ang CDS upang makalikha ito ng archive kapag natapos ang application. Nangangahulugan ito na ang dalawang hakbang sa itaas ay pagsasamahin na ngayon sa isa. At isa pang mahalagang punto: ang mga klase lang na na-load habang tumatakbo ang application ang idadagdag sa archive. Sa madaling salita, ang mga klaseng iyon na nasa application.jar, ngunit sa ilang kadahilanan ay hindi na-load, ay hindi idaragdag sa archive.

I-update ang Socket API

Ang Socket API ( java.net.Socket at java.net.ServerSocket ) ay mahalagang bahagi ng Java mula nang mabuo ito, ngunit ang mga socket ay hindi kailanman na-update sa nakalipas na dalawampung taon. Nakasulat sa C at Java, napakalaki ng mga ito at mahirap pangalagaan. Ngunit nagpasya ang Java 13 na gumawa ng sarili nitong mga pagsasaayos sa buong bagay na ito at pinalitan ang base na pagpapatupad. Ngayon, sa halip na PlainSocketImpl, ang interface ng provider ay pinalitan ng NioSocketImpl . Ang bagong naka-code na pagpapatupad na ito ay batay sa parehong back-end na imprastraktura gaya ng java.nio . Mahalagang ginagamit ng klase ang java.util.concurrent buffer cache at mekanismo ng pag-lock (na nakabatay sa segment) kaysa sa mga naka-synchronize na pamamaraan. Hindi na ito nangangailangan ng native code, na ginagawang mas madali ang pag-port sa iba't ibang platform. Gayunpaman, mayroon kaming paraan upang bumalik sa paggamit ng PlainSocketImpl , ngunit mula ngayon ay ginagamit ang NioSocketImpl bilang default .

Memory Return para sa ZGC

Tulad ng natatandaan namin, ang Z garbage collector ay ipinakilala sa Java 11 bilang isang low-latency na mekanismo ng pangongolekta ng basura upang ang GC na pag-pause ay hindi lalampas sa 10 ms. Ngunit sa parehong oras, hindi tulad ng iba pang mga virtual na GC HotSpot, tulad ng Shenandoah at G1, maaari itong ibalik ang hindi nagamit na dynamic na memorya sa OS. Idinaragdag ng pagbabagong ito ang kakayahang J na ito sa ZGC. Alinsunod dito, nakakakuha kami ng pinababang memory footprint kasama ng pinahusay na pagganap, at ibinabalik ngayon ng ZGC ang hindi naka-commit na memorya sa operating system bilang default hanggang sa maabot ang tinukoy na minimum na laki ng heap. Isa pang bagay: Ang ZGC ay mayroon na ngayong maximum na sinusuportahang laki ng heap na 16 TB. Dati, 4TB ang limitasyon. Iba pang mga inobasyon:
  1. javax.security- Nagdagdag ng property jdk.sasl.disabledMechanismspara hindi paganahin ang mga mekanismo ng SASL.
  2. java.nio- isang paraan ay naidagdag FileSystems.newFileSystem (Path, Map <String,?>)- ayon sa pagkakabanggit, upang lumikha ng isang bagong file.
  3. Ang mga klase java.nioay mayroon na ngayong ganap (kumpara sa kamag-anak) getat set-paraan. Sila, tulad ng base abstract class Buffer, ay may kasamang paraan slice()para sa pagkuha ng bahagi ng buffer.
  4. Nagdagdag ng javax.xml.parsersmga pamamaraan para sa pag-instantiate ng mga pabrika ng DOM at SAX (na may suporta sa namespace).
  5. Ang suporta sa Unicode ay na-update sa bersyon 12.1.
Mga kawili-wiling link sa Java 13:

Mga resulta

Maaari nating talakayin ang mga inihayag na inobasyon sa Java 14, ngunit dahil makikita na nito ang liwanag sa lalong madaling panahon - Ang JDK 14 ay naka-iskedyul na ipalabas sa Marso 17, 2020, pinakamahusay na magsagawa ng isang hiwalay, buong pagsusuri nito kaagad pagkatapos ng paglabas nito . Nais ko ring iguhit ang iyong pansin sa katotohanan na sa iba pang mga programming language na may mahabang pahinga sa pagitan ng mga release, tulad ng Python 2–3, walang compatibility: iyon ay, kung ang code ay nakasulat sa Python 2, ikaw ay kailangang magsumikap sa pagsasalin nito sa 3. Espesyal ang Java sa bagay na ito dahil ito ay lubhang pabalik-balik na katugma. Nangangahulugan ito na ang iyong Java 5 o 8 na programa ay garantisadong tatakbo sa isang Java 8-13 virtual machine—na may ilang mga pagbubukod na hindi mo kailangang alalahanin sa ngayon. Malinaw na hindi ito gumagana sa kabaligtaran: halimbawa, kung ang iyong application ay gumagamit ng Java 13 function na hindi lang available sa Java 8 JVM. Iyon lang ang mayroon ako para sa araw na ito, respeto sa mga nakabasa hanggang sa puntong ito)) Mula 8 hanggang 13: isang kumpletong pangkalahatang-ideya ng mga bersyon ng Java.  Bahagi 2 - 5
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION