JavaRush /Java Blog /Random-ID /Dari 8 hingga 13: gambaran lengkap versi Java. Bagian 2

Dari 8 hingga 13: gambaran lengkap versi Java. Bagian 2

Dipublikasikan di grup Random-ID
Artikel ini adalah bagian kedua dari ulasan saya tentang inovasi di Java versi 8-13. Bagian pertama ada di sini . Tanpa basa-basi lagi, mari kita lanjutkan: ke 25 September 2018, saat JDK baru dirilis:

Jawa 11

Dari 8 hingga 13: gambaran lengkap versi Java.  Bagian 2 - 1

var (dalam lambda)

Mulai sekarang, kita dapat menentukan tipe parameter lambda atau menghilangkannya saat menulis ekspresi lambda (ekspresi lambda yang diketik secara implisit):
Function<String, String> append = (var string) -> string + " Text";
String appendedString = append.apply("Some");
System.out.println(appendedString);
Anda juga dapat menambahkan anotasi ke parameter lambda tanpa harus menulis nama tipe variabel lengkap:
Function<String, String> append = (@NonNull var string) -> string + " Text";

Z(ZGC)

ZGC adalah pengumpul sampah baru yang tidak berfungsi. Ini mengalokasikan memori baru tetapi tidak pernah memulai ulang. ZGC berjanji untuk mengelola memori dalam jumlah besar dengan throughput tinggi dan latensi rendah (ZGC hanya tersedia pada platform 64-bit). Pewarnaan Referensi - ZGC menggunakan pointer 64-bit dengan teknik yang disebut pewarnaan pointer. Pointer berwarna menyimpan informasi tambahan tentang objek di heap. Ketika memori menjadi terfragmentasi, hal ini membantu menghindari penurunan kinerja ketika GC perlu mencari ruang untuk alokasi baru. Pengumpulan sampah menggunakan ZGC terdiri dari langkah-langkah berikut:
  1. world stop: kita mencari titik awal untuk mencapai objek di heap (seperti variabel lokal atau bidang statis);
  2. perpotongan grafik objek mulai dari tautan akar. Kami menandai setiap objek yang kami capai (ZGC menelusuri grafik objek dan memeriksa penanda berwarna, menandai objek yang tersedia);
  3. menangani beberapa kasus tepi, seperti tautan lemah;
  4. memindahkan benda hidup, membebaskan sebagian besar tumpukan untuk mempercepat alokasi.
  5. ketika fase pemindahan dimulai, ZGC membagi tumpukan menjadi beberapa halaman dan mengerjakan satu halaman dalam satu waktu;
  6. ZGC menyelesaikan pergerakan akar mana pun dan sisa pergerakan terjadi.
Topik ini sangat kompleks dan membingungkan. Pembahasan mendetail akan membutuhkan artikel tersendiri, jadi saya tinggalkan saja di sini:

Epsilon GC

Epsilon adalah pengumpul sampah yang menangani alokasi memori tetapi tidak menerapkan mekanisme pemulihan memori yang sebenarnya. Setelah tumpukan Java yang tersedia habis, JVM akan dimatikan. Artinya, jika Anda mulai membuat objek dalam array tak terbatas tanpa mengikat referensi dengan pengumpul sampah ini, aplikasi akan crash dengan OutOfMemoryError (dan jika dengan yang lain, maka tidak akan terjadi, karena akan membersihkan objek tanpa referensi) . Mengapa itu diperlukan? Inilah alasannya:
  1. Pengujian kinerja.
  2. Pengujian tekanan memori.
  3. Menguji antarmuka VM.
  4. Pekerjaan yang sangat singkat.
  5. Peningkatan latensi terakhir.
  6. Peningkatan throughput terakhir.
Tautan yang berguna: Inovasi lainnya:
  1. ByteArrayOutputStreammendapat metode void writeBytes(byte [])yang menulis semua byte dari argumen ke OutputStream.
  2. FileReaderdan FileWritermendapatkan konstruktor baru yang memungkinkan Anda menentukan Charset.
  3. Pathmengambil dua metode baru, of(String, String [])mengembalikan Pathdari argumen string jalur atau urutan string yang bila digabungkan membentuk string jalur dan of(URI): mengembalikan Jalur dari URI.
  4. Pattern— menerima metode asMatchPredicate()yang memeriksa apakah string masukan tertentu cocok dengan pola tertentu (apakah metode tersebut memungkinkan Anda membuat predikat menggunakan ekspresi reguler sehingga Anda dapat, misalnya, memfilter data dalam aliran).
  5. StringSaya mengambil banyak metode berguna, seperti:
    • String strip(): akan mengembalikan kita sebuah string yaitu string ini, dengan semua spasi di awal dan akhir string dihapus (mirip dengan trim(), tetapi mendefinisikan spasi secara berbeda);
    • String stripLeading(): akan mengembalikan kepada kita string yaitu string ini, menghilangkan spasi awal dari string;
    • String stripTrailing(): akan mengembalikan kepada kita string yaitu string ini, menghilangkan spasi apa pun di akhir string;
    • Stream lines(): akan mengembalikan kita Streamdari String, diekstraksi dari string ini, dipisahkan oleh pemisah garis;
    • String repeat(int): akan mengembalikan kepada kita sebuah string yang merupakan gabungan dari string ini, diulang beberapa kali.
    • boolean isBlank(): akan mengembalikan nilai true jika string kosong atau hanya berisi spasi, false jika sebaliknya.
  6. Thread— metode destroy() dan stop(Throwable) telah dihapus.
  7. Filesmendapat sejumlah metode baru:
    • String readString(Path): membaca semua data dari file menjadi string, sementara mendekode dari byte ke karakter menggunakan pengkodean UTF-8;
    • String readString(Path, Charset): sama seperti cara di atas, bedanya decoding dari byte ke karakter terjadi menggunakan Charset yang ditentukan;
    • Path writeString (Path, CharSequence, OpenOption []): Menulis urutan karakter ke file. Karakter dikodekan ke dalam byte menggunakan pengkodean UTF-8;
    • Path writeString(Path, CharSequence,Charset, OpenOption []): Metode yang sama seperti di atas, hanya karakter yang dikodekan menjadi byte menggunakan pengkodean yang ditentukan dalam Charset.
Ini adalah inovasi API yang paling menarik (menurut saya), berikut beberapa materi untuk tinjauan lebih detail:

Jawa 12

Enam bulan berlalu dan kita melihat tahap selanjutnya dalam evolusi Java. Jadi, inilah waktunya untuk mengambil sekop pengetahuan dan menggali. Dari 8 hingga 13: gambaran lengkap versi Java.  Bagian 2 - 2

Perbarui G1

Perbaikan berikut telah dilakukan untuk G1:
  1. Dapatkan kembali memori yang dialokasikan yang tidak digunakan

    Dalam memori heap Java ada yang namanya memori yang tidak terpakai (atau dengan kata lain tidak aktif). Di Java 12 mereka memutuskan untuk memperbaiki masalah ini, sekarang:

    • G1 mengembalikan memori dari heap dalam GC penuh atau selama loop paralel; G1 mencoba mencegah GC penuh dan memulai loop paralel berdasarkan alokasi heap. Kita harus memaksa G1 untuk mengembalikan memori dari heap.

    Peningkatan ini berfokus pada performa dengan mengembalikan memori secara otomatis dari heap ke OS saat G1 tidak digunakan.

  2. Membatalkan koleksi campuran ketika waktu jeda terlampaui

    G1 menggunakan mesin analisis untuk memilih jumlah pekerjaan yang diperlukan untuk pengumpulan sampah. Ia mengumpulkan objek hidup tanpa henti setelah menentukan set dan memulai pembersihan. Hal ini menyebabkan pengumpul sampah melebihi target waktu jedanya. Sebenarnya permasalahan ini dapat diatasi dengan perbaikan, karena jika waktu yang dibutuhkan untuk menyelesaikan langkah selanjutnya melebihi batas wajar maka langkah tersebut dapat dihentikan.

Tolok ukur mikro

Java 12 memperkenalkan pengujian microbenchmarking sehingga performa JVM dapat diuji dengan mudah menggunakan benchmark yang ada. Ini akan sangat berguna bagi siapa saja yang ingin mengerjakan JVM itu sendiri. Tes tambahan dibuat menggunakan Java Microbenchmark Harness (JMH). Pengujian ini memungkinkan pengujian kinerja berkelanjutan pada JVM. JEP 230 mengusulkan pengenalan sekitar 100 pengujian, dengan pengujian baru yang diperkenalkan saat versi baru Java dirilis. Berikut adalah contoh tes yang ditambahkan .

Shenandoah

Ini adalah algoritma pengumpulan sampah (GC) yang bertujuan untuk menjamin waktu respons yang rendah (batas bawah adalah 10-500 ms). Hal ini mengurangi waktu jeda GC saat melakukan pekerjaan pembersihan secara bersamaan dengan menjalankan thread Java. Di Shenandoah, waktu jeda tidak bergantung pada ukuran heap. Ini berarti waktu jeda akan sama terlepas dari ukuran heap Anda. Ini adalah fitur eksperimental dan tidak disertakan dalam versi standar (Oracle) OpenJDK.

Tingkatkan Saklar

Java 12 telah meningkatkan ekspresi Switch untuk pencocokan pola. Sintaks baru L → diperkenalkan. Berikut adalah daftar poin-poin penting dari saklar baru ini :
  1. Sintaks baru menghilangkan kebutuhan akan pernyataan break untuk mencegah kesalahan.
  2. Beralih ekspresi tidak lagi gagal.
  3. Selain itu, kita dapat mendefinisikan beberapa konstanta dalam satu label.
  4. case default sekarang diperlukan dalam ekspresi switch.
  5. break digunakan dalam ekspresi Switch untuk mengembalikan nilai dari register itu sendiri (sebenarnya, switch dapat mengembalikan nilai).
Mari kita lihat ini sebagai contoh:
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.";
  }
};
Panduan Definitif Untuk Mengganti Ekspresi Di Java 13 Fitur baru lainnya:
  1. String:

    transform(Function f)- Menerapkan fungsi yang disediakan ke string. Hasilnya mungkin bukan string.
    indent(int x)— menambahkan spasi x ke string. Jika parameternya negatif, maka jumlah spasi terdepan ini akan dihilangkan (jika memungkinkan).

  2. Files- mengambil metode seperti mismatch(), yang, pada gilirannya, menemukan dan mengembalikan posisi byte pertama yang tidak cocok dalam konten dua file, atau -1L jika tidak ada ketidakcocokan.

  3. Kelas baru telah muncul -CompactNumberFormat untuk memformat angka desimal dalam bentuk yang ringkas. Contoh bentuk ringkas ini adalah 1M, bukan 1,000,000. Jadi, hanya diperlukan dua dua, bukan sembilan karakter.

  4. Ada juga yang baru enum , NumberFormatStyleyang memiliki dua nilai - PANJANG dan PENDEK.

  5. InputStream dapatkan metodenya skipNBytes(long n) : lewati jumlah byte ke-n dari aliran input.

Tautan Java 12 yang menarik:

Jawa 13

Dunia tidak tinggal diam, ia bergerak, ia berkembang, seperti Java – Java 13. Dari 8 hingga 13: gambaran lengkap versi Java.  Bagian 2 - 3

Blok teks

Java selalu mengalami kesulitan dalam mendefinisikan string. Jika kita perlu mendefinisikan sebuah baris dengan spasi, jeda baris, tanda kutip atau yang lainnya, hal ini menyebabkan beberapa kesulitan, jadi kita harus menggunakan karakter khusus: misalnya, \n untuk jeda baris, atau keluar dari beberapa baris diri. Ini secara signifikan mengurangi keterbacaan kode dan membutuhkan waktu ekstra saat menulis baris tersebut. Hal ini terutama terlihat ketika menulis string yang menampilkan JSON, XML, HTML, dll. Hasilnya, jika kita ingin menulis Json kecil, tampilannya akan seperti ini:
String JSON_STRING = "{\r\n" + "\"name\" : \"someName\",\r\n" + "\"site\" : \"https://www.someSite.com/\"\r\n" + "}";
Dan kemudian Java 13 hadir dan menawarkan kepada kita solusinya dalam bentuk tanda kutip ganda tiga kali lipat sebelum dan sesudah teks (yang mereka sebut blok teks). Mari kita lihat contoh json sebelumnya yang menggunakan inovasi ini:
String TEXT_BLOCK_JSON = """
{
    "name" : "someName",
    "site" : "https://www.someSite.com/"
}
""";
Jauh lebih sederhana dan jelas, bukan? StringTiga metode baru juga ditambahkan untuk mengelola blok ini:
  • stripIndent(): Menghapus spasi acak dari sebuah string. Ini berguna jika Anda membaca string multiline dan ingin menerapkan jenis pengecualian spasi acak yang sama seperti yang terjadi dengan deklarasi eksplisit (pada dasarnya menyimulasikan kompiler untuk menghapus spasi acak);
  • formatted(Object... args ): mirip dengan format(String format, Object... arg), tetapi untuk blok teks;
  • translateEscapes(): Mengembalikan string dengan urutan escape (seperti \r) yang diterjemahkan ke nilai Unicode yang sesuai.

Tingkatkan Saklar

Ekspresi peralihan diperkenalkan di Java 12, dan 13 menyempurnakannya. Di 12 Anda menentukan nilai pengembalian menggunakan break. Di 13, nilai kembalian diganti dengan hasil. Sekarang ekspresi switch yang kita miliki di bagian Java 12 dapat ditulis ulang sebagai:
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.";
  }
};
Meskipun normal bagi kami para programmer yang sudah familiar dengan Java untuk menerima break, namun hal ini cukup aneh. Apa yang ingin disampaikan oleh break true kepada saya? Kata kunci hasil yang baru (relatif baru) lebih jelas dan mungkin muncul di tempat lain di masa mendatang di mana nilai dikembalikan. Bagi mereka yang sangat tertarik dengan topik ini, saya sarankan Anda membaca materi berikut:

Arsip CDS Dinamis

CDS - Berbagi Data Kelas. Memungkinkan Anda mengemas sekumpulan kelas yang umum digunakan ke dalam arsip yang nantinya dapat dimuat oleh beberapa instance JVM. Kenapa kita perlu ini? Faktanya adalah bahwa dalam proses memuat kelas, JVM melakukan cukup banyak tindakan intensif sumber daya, seperti membaca kelas, menyimpannya dalam struktur internal, memeriksa kebenaran kelas yang dibaca, mencari dan memuat kelas dependen, dll. ., dan hanya setelah semua ini kelas siap untuk bekerja. Maklum, banyak sumber daya yang terbuang, karena instance JVM sering kali memuat kelas yang sama. Misalnya String, LinckedList, Integer. Ya, atau kelas dari aplikasi yang sama, dan semuanya adalah sumber daya. Jika kita melakukan semua langkah yang diperlukan sekali saja dan kemudian menempatkan kelas yang didesain ulang dalam arsip yang dapat dimuat ke dalam memori beberapa JVM, ini dapat menghemat ruang memori secara signifikan dan mengurangi waktu startup aplikasi. Sebenarnya, CDS memungkinkan pembuatan arsip seperti itu. Java 9 hanya mengizinkan kelas sistem ditambahkan ke arsip. Java 10 - sertakan kelas aplikasi dalam arsip. Pembuatan arsip tersebut terdiri dari:
  • membuat daftar kelas yang dimuat oleh aplikasi;
  • membuat arsip yang sangat dibutuhkan dengan kelas-kelas yang kami temukan.
Inovasi pada Java 13 meningkatkan CDS sehingga dapat membuat arsip ketika aplikasi dihentikan. Artinya kedua langkah di atas kini akan digabungkan menjadi satu. Dan satu lagi poin penting: hanya kelas yang dimuat saat aplikasi sedang berjalan yang akan ditambahkan ke arsip. Dengan kata lain, kelas-kelas yang masih terdapat di application.jar, tetapi karena alasan tertentu tidak dimuat, tidak akan ditambahkan ke arsip.

Perbarui API Soket

Socket API ( java.net.Socket dan java.net.ServerSocket ) pada dasarnya merupakan bagian integral dari Java sejak awal, tetapi soket tidak pernah diperbarui dalam dua puluh tahun terakhir. Ditulis dalam C dan Java, ukurannya sangat, sangat besar dan sulit dirawat. Namun Java 13 memutuskan untuk membuat penyesuaian sendiri terhadap seluruh masalah ini dan menggantikan implementasi dasar. Sekarang, alih-alih PlainSocketImpl, antarmuka penyedia diganti dengan NioSocketImpl . Implementasi kode baru ini didasarkan pada infrastruktur back-end yang sama dengan java.nio . Pada dasarnya kelas menggunakan cache buffer java.util.concurrent dan mekanisme penguncian (yang berbasis segmen) daripada metode yang disinkronkan. Ini tidak lagi memerlukan kode asli, sehingga lebih mudah untuk porting ke platform yang berbeda. Namun, kami memiliki cara untuk kembali menggunakan PlainSocketImpl , tetapi mulai sekarang NioSocketImpl digunakan secara default .

Pengembalian Memori untuk ZGC

Seperti yang kita ingat, pengumpul sampah Z diperkenalkan di Java 11 sebagai mekanisme pengumpulan sampah berlatensi rendah sehingga jeda GC tidak pernah melebihi 10 ms. Namun pada saat yang sama, tidak seperti HotSpot GC virtual lainnya, seperti Shenandoah dan G1, ini dapat mengembalikan memori dinamis yang tidak terpakai ke OS. Modifikasi ini menambahkan kemampuan J ini ke ZGC. Oleh karena itu, kami mendapatkan pengurangan jejak memori seiring dengan peningkatan kinerja, dan ZGC kini mengembalikan memori yang tidak terikat ke sistem operasi secara default hingga ukuran heap minimum yang ditentukan tercapai. Satu hal lagi: ZGC kini memiliki ukuran heap maksimum yang didukung sebesar 16 TB. Sebelumnya, 4TB adalah batasnya. Inovasi lainnya:
  1. javax.security- menambahkan properti jdk.sasl.disabledMechanismsuntuk menonaktifkan mekanisme SASL.
  2. java.nio- sebuah metode telah ditambahkan FileSystems.newFileSystem (Path, Map <String,?>)- masing-masing, untuk membuat file baru.
  3. Kelas java.niosekarang memiliki metode absolut (bukan relatif) getdan set-. Mereka, seperti kelas abstrak dasar Buffer, menyertakan metode slice()untuk mengambil bagian dari buffer.
  4. Menambahkan javax.xml.parsersmetode untuk membuat instance pabrik DOM dan SAX (dengan dukungan namespace).
  5. Dukungan Unicode telah diperbarui ke versi 12.1.
Tautan menarik di Java 13:

Hasil

Kita dapat membahas inovasi yang diumumkan pada Java 14, namun karena inovasi ini akan segera terungkap - JDK 14 dijadwalkan untuk dirilis pada 17 Maret 2020, sebaiknya lakukan peninjauan terpisah dan menyeluruh segera setelah dirilis. . Saya juga ingin menarik perhatian Anda pada fakta bahwa dalam bahasa pemrograman lain dengan jeda panjang antar rilis, seperti Python 2–3, tidak ada kompatibilitas: yaitu, jika kode ditulis dalam Python 2, Anda akan melakukannya perlu bekerja keras menerjemahkannya ke 3. Java istimewa dalam hal ini karena sangat kompatibel ke belakang. Ini berarti program Java 5 atau 8 Anda dijamin berjalan di mesin virtual Java 8-13—dengan beberapa pengecualian yang tidak perlu Anda khawatirkan untuk saat ini. Jelas bahwa ini tidak berlaku sebaliknya: misalnya, jika aplikasi Anda menggunakan fungsi Java 13 yang tidak tersedia di Java 8 JVM. Itu saja untuk saya hari ini, hormat kepada mereka yang telah membaca sampai saat ini)) Dari 8 hingga 13: gambaran lengkap versi Java.  Bagian 2 - 5
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION