JavaRush /Java блогу /Random-KY /8ден 13кө чейин: Java версияларына толук сереп салуу. 2 б...
Константин
Деңгээл

8ден 13кө чейин: Java версияларына толук сереп салуу. 2 бөлүк

Группада жарыяланган
Бул макала менин Java 8-13 versionларындагы инновацияларды карап чыгуумдун экинчи бөлүгү. Биринчи бөлүгү бул жерде . Андан ары созбой, келгиле уланталы: 2018-жылдын 25-сентябрына чейин, жаңы JDK чыкканда:

Java 11

8ден 13кө чейин: Java versionларына толук сереп салуу.  2-1-бөлүк

var (ламбдада)

Мындан ары ламбда туюнтмасын жазууда ламбда параметрлеринин түрлөрүн көрсөтпөй койсок болот (жабыртылган лямбда туюнтмалары):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Сиз ошондой эле толук өзгөрмө түрүнүн атын жазбастан lambda параметрлерине annotationларды кошо аласыз:
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

ZGC жаңы таштанды жыйноочу, ал иштебейт. Ал жаңы эстутумду бөлүп берет, бирок аны эч качан өчүрбөйт. ZGC чоң көлөмдөгү эстутумду жогорку өткөрүү жана аз күтүү менен башкарууну убада кылат (ZGC 64 биттик платформаларда гана жеткorктүү). Шилтеме Coloring - ZGC көрсөткүчтү боёо деп аталган ыкма менен 64-бит көрсөткүчтөрдү колдонот. Түстүү көрсөткүчтөр үймөктөгү an objectтер жөнүндө кошумча маалыматты сактайт. Эстутум фрагменттелгенде, бул GC жаңы бөлүштүрүү үчүн орун табышы керек болгондо, иштин начарлашынан сактайт. ZGC аркылуу таштанды чогултуу төмөнкү кадамдардан турат:
  1. дүйнөлүк аялдамалар: үймөктөгү an objectтерге жетүү үчүн баштапкы чекиттерди издейбиз (мисалы, жергorктүү өзгөрмөлөр же статикалык талаалар);
  2. негизги шилтемелерден баштап an object графиктеринин кесorши. Биз жеткен ар бир an objectти белгилейбиз (ZGC an objectтин графигин басып өтүп, жеткorктүү an objectтерди белгилөө менен түстүү маркерлерди карап чыгат);
  3. кээ бир четки учурларды иштетүү, мисалы, алсыз шилтемелер;
  4. тирүү an objectтерди жылдыруу, бөлүштүрүүнү тездетүү үчүн үймөктүн чоң аймактарын бошотуу.
  5. жылдыруу фазасы башталганда, ZGC үймөктү барактарга бөлүп, бир эле учурда бир баракты иштейт;
  6. ZGC ар кандай тамырлардын кыймылын аяктайт жана калган кыймыл пайда болот.
Бул тема абдан татаал жана чаташкан. Толук талкуулоо өзүнчө макаланы талап кылат, ошондуктан мен аны бул жерге калтырам:

Epsilon GC

Epsilon эстутум бөлүштүрүүнү иштеткен таштанды жыйноочу, бирок эстутумду калыбына келтирүү механизмин ишке ашырbyte. Жеткorктүү Java үймөгү түгөнгөндөн кийин, JVM жабылат. Башкача айтканда, эгер сиз бул таштанды жыйноочу менен шилтеме менен байланышпай эле чексиз массивде an object түзө баштасаңыз, тиркеме OutOfMemoryError менен бузулат (жана башкасы менен болсо, андай болбойт, анткени ал an objectтерди шилтемесиз тазалайт. ). Бул эмне үчүн керек? Бул жерде эмне үчүн:
  1. Performance testing.
  2. Эстутум басымын текшерүү.
  3. VM интерфейси сыналууда.
  4. Абдан кыска иш.
  5. Акыркы түшүү күтүү мөөнөтү жакшыртылды.
  6. Акыркы түшүү өткөрүү жөндөмдүүлүгү жакшыртылды.
Пайдалуу шилтемелер: Башка инновациялар:
  1. ByteArrayOutputStreamvoid writeBytes(byte [])аргументтен бардык byteтарды жаза турган ыкмага ээ болду OutputStream.
  2. FileReaderжана FileWriterCharsetти көрсөтүүгө мүмкүндүк берген жаңы конструкторлорду алды.
  3. Pathэки жаңы ыкманы кармады, сап аргументинен жолду же саптардын ырааттуулугун of(String, String [])кайтарат , алар бириккенде жол саптарын түзөт жана : URIдан Path кайтарат.Pathof(URI)
  4. Pattern— берилген киргизүү сап берилген үлгүгө дал келээрин текшерген метод алды asMatchPredicate()(ал регулярдуу туюнтманы колдонуп предикатты түзүүгө мүмкүндүк береби, мисалы, агымдагы маалыматтарды чыпкалоо үчүн).
  5. StringМен көптөгөн пайдалуу ыкмаларды тандап алдым, мисалы:
    • String strip(): бизге ушул сап болгон сапты кайтарат, саптын башында жана аягындагы бардык боштуктар алынып салынган (trim()га окшош, бирок боштуктарды башкача аныктайт);
    • String stripLeading(): саптан бардык алдыңкы боштуктарды алып салып, бул сапты бизге кайтарат;
    • String stripTrailing(): саптын аягындагы боштуктарды алып салуу менен бизге бул сапты кайтарып берет;
    • Stream lines()Stream: бизди кайтарат String, бул саптан алынган, сызык бөлгүчтөр менен бөлүнгөн;
    • String repeat(int): бизге бир нече жолу кайталанган бул саптын бириктирorши болгон сапты кайтарат.
    • boolean isBlank(): эгер сап бош болсо же боштуктар гана камтылса true, антпесе false кайтарып берет.
  6. Thread— destroy() жана stop(Throwable) ыкмалары алынып салынды.
  7. Filesбир катар жаңы ыкмалар бар:
    • String readString(Path): UTF-8 codeдоосун колдонуп, byteтардан символдорго чейин деcodeдоодо файлдагы бардык маалыматтарды сапка окуйт;
    • String readString(Path, Charset): жогорудагы ыкмадагыдай эле, айырмасы менен byteтан символго деcodeдоо көрсөтүлгөн Charset аркылуу ишке ашат;
    • Path writeString (Path, CharSequence, OpenOption []): Файлга символдордун ырааттуулугун жазат. Белгилер UTF-8 codeдоосу аркылуу byteтарга codeдолгон;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Жогорудагыдай эле ыкма, Charsetте көрсөтүлгөн codeдоону колдонуу менен символдор гана byteтарга codeдолот.
Бул эң кызыктуу API инновациялары болгон (менин оюмча), бул жерде кененирээк карап чыгуу үчүн бир нече материалдар бар:

Java 12

Алты ай өтөт жана биз Java эволюциясынын кийинки баскычын көрүп жатабыз. Демек, бorмдин күрөгүн алып, казууга убакыт келди. 8ден 13кө чейин: Java versionларына толук сереп салуу.  2-2-бөлүк

G1 жаңыртуу

G1 үчүн төмөнкү жакшыртуулар жасалды:
  1. Колдонулбаган эстутумду калыбына келтириңиз

    Java үймө эсинде пайдаланылбаган эс (же башкача айтканда, жигердүү эмес) сыяктуу нерсе бар. Java 12де алар бул көйгөйдү чечүүнү чечишти, азыр:

    • G1 толук GC же параллелдүү цикл учурунда үймөктөн эстутумду кайтарат; G1 толук GC алдын алууга аракет кылат жана үймөк бөлүштүрүүнүн негизинде параллелдүү циклди баштайт. Биз G1ди үймөктөн эстутумду кайтарууга мажбурлашыбыз керек.

    Бул өркүндөтүү G1 колдонулбай турганда эстутумду үймөктөн OSке автоматтык түрдө кайтарып, аткарууга багытталган.

  2. Тыныгуу убактысы ашып кеткенде аралаш коллекциялар токтотулат

    G1 таштанды чогултуу үчүн зарыл болгон иштин көлөмүн тандоо үчүн талдоо кыймылдаткычын колдонот. Ал топтомду аныктап, тазалоону баштагандан кийин токтобостон жандуу an objectтерди чогултат. Бул таштанды жыйгычтын тыныгуу убактысынын максатынан ашып кетишине алып келет. Чынында, бул маселе жакшыртуу жолу менен чечилет, анткени кийинки кадамды аяктоо үчүн талап кылынган убакыт акылга сыярлык чектен ашса, бул кадам үзгүлтүккө учурашы мүмкүн.

Микробенчмарк

Java 12 микробенчмаркинг тесттерин киргизди, ошентип JVM иштеши учурдагы эталондорду колдонуу менен оңой сыналышы мүмкүн. Бул JVMдин өзүндө иштөөнү каалагандар үчүн абдан пайдалуу болмок. Кошулган тесттер Java Microbenchmark Harness (JMH) аркылуу түзүлөт. Бул тесттер JVMде үзгүлтүксүз иштөөнү текшерүүгө мүмкүндүк берет. JEP 230 болжол менен 100 тестти киргизүүнү сунуштайт, жаңы тесттер Java жаңы versionлары чыкканда киргизилген. Бул жерде кошулуп жаткан сыноолордун мисалы .

Shenandoah

Бул таштанды чогултуу (GC) алгоритми, анын максаты жооп берүү убактысынын төмөндүгүн камсыз кылуу (төмөнкү чек 10-500 мс). Бул Java жиптерин иштетүү менен бир убакта тазалоо иштерин аткарып жатканда GC тыныгуу убактысын кыскартат. Шенандоада тыныгуу убактысы үймөктүн көлөмүнө көз каранды эмес. Бул тыныгуу убактысы үймөктүн көлөмүнө карабастан бирдей болот дегенди билдирет. Бул эксперименталдык функция жана OpenJDK стандарттык (Oracle) түзүмүнө кирбейт.

Которуштурууну жакшыртуу

Java 12 үлгү дал келүү үчүн Switch туюнтмаларын жакшыртты. Жаңы L → синтаксиси киргизилди. Бул жерде жаңы алмаштыргычтын негизги пункттарынын тизмеси :
  1. Жаңы синтаксис каталарды болтурбоо үчүн break операторунун зарылдыгын жок кылат.
  2. Которуу туюнтмалары мындан ары иштебейт.
  3. Мындан тышкары, биз бир энбелгиде бир нече туруктууларды аныктай алабыз.
  4. демейки регистр азыр которуштуруу туюнтмаларында талап кылынат.
  5. break реестрдин өзүнөн маанилерди кайтаруу үчүн Switch туюнтмаларында колдонулат (чындыгында, которгуч маанилерди кайтара алат).
Муну мисал катары карап көрөлү:
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'те туюнтмаларды которуу үчүн анык колдонмо Башка жаңы функциялар:
  1. String:

    transform(Function f)- Берилген функцияны сапка колдонот. Натыйжа сап болбошу мүмкүн.
    indent(int x)— сапка x боштуктарды кошот. Эгерде параметр терс болсо, анда алдыңкы боштуктардын бул саны алынып салынат (мүмкүн болсо).

  2. Files- сыяктуу ыкманы кармады mismatch(), ал өз кезегинде эки файлдын мазмунунан биринчи дал келбеген byteтын ордун таап, кайтарат, же дал келбегендик болбосо -1L.

  3. Жаңы класс пайда болду -CompactNumberFormat ондук санды компакт түрүндө форматтоо үчүн. Бул компакт форманын мисалы 1 000 000 ордуна 1M. Ошентип, тогуз белгинин ордуна эки гана эки керек.

  4. Ошондой эле жаңысы бар enum, NumberFormatStyleанын эки мааниси бар - УЗУН жана КЫСКА.

  5. InputStream ыкмасын алды skipNBytes(long n) : киргизүү агымынан byteтардын n-санын өткөрүп жиберүү.

Кызыктуу Java 12 шилтемелери:

Java 13

Дүйнө бир ордунда турbyte, кыймылдайт, Java - Java 13 сыяктуу өнүгүп жатат. 8ден 13кө чейин: Java versionларына толук сереп салуу.  2-3-бөлүк

Текст блогу

Java ар дайым саптарды аныктоодо бир аз кыйналган. Эгерде сапты боштук, сызык үзүү, тырмакча же башка бир нерсе менен аныктоо керек болсо, бул кээ бир кыйынчылыктарды жаратты, ошондуктан биз атайын символдорду колдонууга туура келди: мисалы, \n сызык үзүлүшү үчүн же саптын айрым бөлүгүн качуу өзү. Бул codeдун окулушун кыйла азайтат жана мындай сапты жазууда кошумча убакытты талап кылат. Бул JSON, XML, HTML ж.б. көрсөткөн саптарды жазганда өзгөчө байкалат. Натыйжада, биз кичинекей Json жазгыбыз келсе, ал төмөнкүдөй болот:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
Анан Java 13 сахнага келип, бизге тексттин алдында жана андан кийин үч эселенген кош тырмакчалар түрүндө өзүнүн чечимин сунуштайт (алар текст блоктору деп аташкан). Бул инновацияны колдонуу менен мурунку json мисалын карап көрөлү:
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
алда канча жөнөкөй жана түшүнүктүү, туурабы? StringБул блокторду башкаруу үчүн үч жаңы ыкма дагы кошулду:
  • stripIndent(): Саптан туш келди боштуктарды жок кылат. Эгер сиз көп сап саптарын окуп жатсаңыз жана ачык декларацияда пайда болгон кокус боштуктун бирдей түрүн колдонгуңуз келсе, бул пайдалуу (негизинен кокус боштуктарды алып салуу үчүн компиляторду имитациялоо);
  • formatted(Object... args ): окшош format(String format, Object... arg), бирок текст блоктору үчүн;
  • translateEscapes(): Тиешелүү Юниcode маанисине которулган качуу ырааттуулугу (мисалы, \r) менен сапты кайтарат.

Которуштурууну жакшыртуу

Которуу туюнтмалары Java 12де киргизилген жана 13 аларды тактайт. 12де сиз кайтуучу маанилерди break аркылуу аныктайсыз. 13-жылы кайтарым мааниси кирешелүүлүк менен алмаштырылган. Эми Java 12 бөлүмүндө болгон которгуч туюнтманы төмөнкүдөй кайра жазууга болот:
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.";
  }
};
Биз Java менен тааныш болгон программисттер үчүн тыныгууну кабыл алуу нормалдуу болгонуна карабастан, бул абдан кызык болчу. Мага айткысы келген чындык деген эмне? Жаңы (салыштырмалуу жаңы) кирешелүү ачкыч сөз айкыныраак жана келечекте баалуулуктар кайтарылган башка жерлерде пайда болушу мүмкүн. Бул темага терең кызыккандар үчүн мен сизге бул материалдар менен таанышууну сунуштайм:

Динамикалык CDS архивдери

CDS - Class-Data Sharing. Көбүнчө колдонулган класстардын топтомун кийинчерээк бир нече JVM инстанциялары жүктөй турган архивге пакеттөө мүмкүнчүлүгүн берет. Бул бизге эмне үчүн керек? Чындыгында, класстарды жүктөө процессинде JVM көптөгөн ресурстарды талап кылган аракеттерди жасайт, мисалы окуу класстарын, аларды ички структураларда сактоо, окуу класстарынын тууралыгын текшерүү, көз каранды класстарды издөө жана жүктөө ж.б.у.с. ., Ошондон кийин гана класстар иштөөгө даяр. Түшүнүктүү, көп ресурстар текке кетет, анткени JVM инстанциялары көбүнчө бир эле класстарды жүктөй алышат. Мисалы, String, LinkedList, Integer. Ооба, же бир эле колдонмонун класстары жана булардын баары ресурстар. Эгерде биз бардык керектүү кадамдарды бир эле жолу аткарып, анан кайра иштелип чыккан класстарды бир нече JVMдин эстутумуна жүктөй турган архивге жайгаштырсак, бул эс тутумдун мейкиндигин бир топ үнөмдөп, тиркемени ишке киргизүү убактысын кыскартат. Чынында, CDS ушундай архивди түзүүгө мүмкүндүк берет. Java 9 тутум класстарын архивге кошууга гана уруксат берген. Java 10 - архивге колдонмо класстарын кошуу. Мындай архивди түзүү төмөнкүлөрдөн турат:
  • тиркеме тарабынан жүктөлгөн класстардын тизмесин түзүү;
  • биз тапкан класстар менен абдан керектүү архивди түзүү.
Java 13 инновациясы CDSти жакшыртат, андыктан ал тиркеме аяктаганда архив түзө алат. Бул жогорудагы эки кадам эми бир кадамга бириктирилет дегенди билдирет. Жана дагы бир маанилүү жагдай: колдонмо иштеп турганда жүктөлгөн класстар гана архивге кошулат. Башкача айтканда, application.jar ичинде дагы эле камтылган, бирок кандайдыр бир себептерден улам жүктөлбөй калган класстар архивге кошулbyte.

Socket API жаңыртуу

Socket API ( java.net.Socket жана java.net.ServerSocket ) түпкүлүгүндө Javaнын ажырагыс бөлүгү болуп саналат, бирок розеткалар акыркы жыйырма жылда бир да жолу жаңыртылган эмес. C жана Java тилдеринде жазылган, алар абдан көлөмдүү жана сактоо кыйын болгон. Бирок Java 13 бул маселеге өзүнүн оңдоп-түзөөлөрүн жасоону чечти жана базаны ишке ашырууну алмаштырды. Эми, PlainSocketImpl ордуна , камсыздоочу интерфейси NioSocketImpl менен алмаштырылды . Бул жаңы codeдолгон ишке ашыруу java.nio сыяктуу эле арткы инфраструктурага негизделген . Негизи класс синхрондоштурулган методдордон көрө java.util.concurrent буфер кэшин жана кулпулоо механизмин (сегментке негизделген) колдонот. Ал мындан ары жергorктүү codeду талап кылbyte, бул ар кандай платформаларга өтүүнү жеңилдетет. Ошентсе да, бизде PlainSocketImpl колдонууга кайтуу жолу бар , бирок мындан ары NioSocketImpl демейки боюнча колдонулат .

ZGC үчүн эстутумду кайтаруу

Эсибизде болгондой, Z таштанды жыйноочу Java 11де GC тыныгуусу эч качан 10 мс ашпашы үчүн, аз күтүлүүчү таштанды чогултуу механизми катары киргизилген. Бирок ошол эле учурда, Shenandoah жана G1 сыяктуу башка виртуалдык GC HotSpots айырмаланып, ал OS үчүн пайдаланылбаган динамикалык эстутумду кайтарып бере алат. Бул өзгөртүү ZGC бул J мүмкүнчүлүгүн кошот. Демек, биз жакшыртылган иштөө менен бирге эстутумдун көлөмүн азайтабыз жана ZGC эми белгиленген минималдуу үймөк өлчөмүнө жеткенге чейин демейки боюнча операциялык тутумга бекитилбеген эстутумду кайтарып берет. Дагы бир нерсе: ZGC азыр 16 ТБ максималдуу колдоого алынган үймөк өлчөмүнө ээ. Буга чейин 4ТБ чек болгон. Башка инновациялар:
  1. javax.securityjdk.sasl.disabledMechanisms- SASL механизмдерин өчүрүү үчүн касиет кошулду .
  2. java.nio- ыкмасы кошулду FileSystems.newFileSystem (Path, Map <String,?>)- тиешелүүлүгүнө жараша, жаңы файлды түзүү.
  3. Класстарда java.nioазыр абсолюттук (салыштырмалуудан айырмаланып) getжана set-методдор бар. Алар, базалык абстракттуу класс сыяктуу , буфердин бир бөлүгүн алуу Bufferыкмасын камтыйт .slice()
  4. DOM жана SAX фабрикаларын түзүү үчүн кошумча javax.xml.parsersыкмалар (ат мейкиндигин колдоосу менен).
  5. Юниcodeдун колдоосу 12.1 versionсына жаңыртылган.
Java 13 боюнча кызыктуу шилтемелер:

Жыйынтыктар

Биз Java 14-де жарыяланган инновацияларды карап чыксак болот, бирок ал жакында жарык көрөт - JDK 14 2020-жылдын 17-мартында чыгышы пландаштырылган, аны чыккандан кийин дароо өзүнчө, толук карап чыгуу жакшы болмок . Мен ошондой эле Python 2–3 сыяктуу релиздердин ортосунда узак тыныгуулар бар башка программалоо тилдеринде эч кандай шайкештик жок экендигине көңүлүңүздү бургум келет: башкача айтканда, эгер code Python 2де жазылган болсо, сиз аны которуу үчүн талыкпай иштөө керек 3. Java бул жагынан өзгөчө, анткени ал өтө артка шайкеш келет. Бул сиздин Java 5 же 8 программаңыз Java 8-13 виртуалдык машинасында иштөөгө кепилдик берилет дегенди билдирет — бир нече бөтөнчөлүктөрдү эске албаганда, сиз азыр тынчсыздануунун кереги жок. Бул башка жол менен иштебей турганы түшүнүктүү: мисалы, сиздин колдонмоңуз Java 8 JVMде жок Java 13 функцияларын колдонсо. Бугунку кунум ушул эле, ушул убакка чейин окугандарга таазим)) 8ден 13кө чейин: Java versionларына толук сереп салуу.  2-5-бөлүк
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION