Alasan untuk pindah ke Java 25

Java 25 adalah rilis dukungan jangka panjang (LTS), yang menjadikannya target alami bagi tim yang berjalan pada Java 8, 11, 17, atau 21 hari ini. Setiap rilis LTS menerima pembaruan dan perbaikan keamanan selama bertahun-tahun, jadi pindah ke Java 25 menjaga aplikasi Anda tetap didukung, aman, dan dapat menggunakan peningkatan performa dan bahasa terbaru.

Pertanyaannya bukan jika Anda harus pindah ke rilis LTS yang lebih baru, tetapi kapan. Semakin lama Anda menunggu, semakin banyak perubahan yang terakumulasi antara versi Anda saat ini dan yang didukung berikutnya. Ada manfaat yang jelas untuk pindah ke Java 25, dan merencanakan pemindahan lebih cepat daripada nanti mengurangi risiko.

Sejak Java 8, setiap rilis telah menambahkan fitur dan peningkatan. Ada penambahan dan modifikasi yang nyata pada API, bersama dengan peningkatan waktu startup, throughput, penggunaan memori, skalabilitas, dan produktivitas pengembang. Artikel ini menyoroti perubahan yang paling berdampak, dengan fokus pada versi Java yang dikirimkan sejak rilis Java 11 LTS: Java 17, Java 21, dan Java 25.

Transisi ke Java 25

Anda dapat beralih ke Java 25 secara bertahap. Kode yang dikembangkan dan dibangun dengan JDK yang lebih lama biasanya dapat berjalan pada Java 25 tanpa kompilasi ulang. Seperti halnya peningkatan besar apa pun, perhatikan API yang dihapus, paket yang tidak digunakan lagi, penggunaan API internal, dan perubahan pada perilaku default, terutama di sekitar pengumpulan sampah.

Jika Anda berasal dari Java 8 atau 11, mulailah dengan panduan transisi dari Java 8 ke Java 11 untuk mengatasi serangkaian perubahan mencolok terbesar, lalu lanjutkan ke Java 17, 21, dan 25. Jika Anda sudah menggunakan Java 17 atau 21, perpindahan ke Java 25 biasanya lebih kecil karena sistem modul dan sebagian besar perubahan platform sudah ada di belakang Anda.

Tip

Modernisasi gitHub aplikasi Copilot dapat membantu Anda menilai aplikasi, merencanakan peningkatan, dan menerapkan perubahan kode secara otomatis. Ini mendukung peningkatan antara Java versi 8, 11, 17, 21, dan 25, membangun dan menguji proyek Anda setelah setiap perubahan, dan membantu memulihkan perubahan perilaku yang dijelaskan nanti dalam artikel ini.

Tip

Bendera JVM yang disetel untuk JDK yang lebih lama dapat menjadi tidak digunakan lagi, dihapus, atau suboptimal pada Java 25. Alih-alih mempertahankan pengaturan usang, Anda dapat membiarkan Azure Command Launcher untuk Java (jaz) secara otomatis menerapkan flag JVM yang disesuaikan dengan versi JDK serta resource kontainer atau mesin virtual Anda. java Ganti perintah dengan jaz dalam skrip peluncuran Anda atau Dockerfile untuk mendapatkan manfaat.

Perubahan tingkat tinggi sejak Java 11

Bagian ini tidak menghitung setiap perubahan yang dilakukan sejak Java 8. Ini menyoroti perubahan yang memiliki dampak terbesar pada performa, skalabilitas, diagnostik, produktivitas, dan keamanan. Sebagian besar fitur ini tiba di rilis Java 17, 21, dan 25 dan sekarang menjadi bagian dari garis besar LTS yang Anda dapatkan dengan Java 25. Setiap fitur mencatat rilis Java yang diintegrasikan.

Skalabilitas dengan utas virtual

Utas virtual [1] adalah utas ringan yang dikelola oleh JVM, bukan oleh sistem operasi, yang secara signifikan mengurangi biaya untuk menulis dan menjalankan aplikasi konkuren dengan throughput tinggi. Dengan utas virtual, Anda dapat menulis kode dengan gaya sederhana satu utas per permintaan dan tetap dapat menangani operasi konkuren dalam jumlah besar, yang ideal untuk layanan mikro yang terikat pada I/O dan beban kerja permintaan-respons.

Utas virtual diselesaikan dalam Java 21. Java 24 menghapus keterbatasan utama dengan memungkinkan utas virtual melakukan sinkronisasi tanpa menyematkan utas pembawanya [2], yang meningkatkan skalabilitas untuk kode yang menggunakan blok synchronized.

Konkurensi terstruktur dan nilai cakupan

Nilai tercakup [3] menyediakan cara yang aman dan efisien untuk berbagi data yang tidak dapat diubah di dalam dan di seluruh utas, termasuk utas virtual. Ini merupakan alternatif modern untuk variabel thread-local yang cocok digunakan dengan model thread-per-task.

Konkurensi terstruktur [4] memperlakukan grup tugas bersamaan terkait sebagai satu unit kerja, yang menyederhanakan penanganan kesalahan dan pembatalan. Pertama kali dipratinjau dalam Java 21, ia terus berkembang dan berpasangan secara alami dengan utas virtual.

Produktivitas bahasa

Serangkaian penyempurnaan bahasa yang dikirimkan di Java 14 hingga Java 25 membuat kode lebih ringkas, lebih aman, dan lebih mudah dibaca:

  • Beralih ekspresi [5] (Java 14) memungkinkan switch mengembalikan nilai dan menggunakan sintaks panah yang lebih bersih.
  • Pencocokan pola untuk instanceof [6] (Java 16) menghilangkan kebutuhan untuk konversi tipe eksplisit setelah pemeriksaan tipe.
  • Record [7] (Java 16) digunakan untuk memodelkan data yang tidak dapat diubah sebagai pembawa transparan untuk sekumpulan nilai tetap, sehingga mengurangi kode boilerplate.
  • Kelas yang disegel [8] (Java 17) memungkinkan Anda mengontrol kelas mana yang dapat memperluas atau mengimplementasikan jenis.
  • Blok teks [9] (Java 15) menyederhanakan penulisan literal string multibaris.
  • Pencocokan pola untuk switch [10] (Java 21) dan pola rekaman [11] (Java 21) memungkinkan Anda mengekspresikan logika bersyarat yang kompleks dan penghancuran data dengan jelas dan aman.
  • Koleksi berurutan [12] (Java 21) menambahkan API seragam untuk koleksi dengan urutan pertemuan yang ditentukan, termasuk akses ke elemen pertama dan terakhir.
  • Variabel dan pola yang tidak disebutkan namanya [13] (Java 22) memungkinkan Anda menandai variabel dan komponen pola yang tidak digunakan secara eksplisit.
  • Deklarasi impor modul [14] (Java 25) memungkinkan Anda mengimpor seluruh paket modul yang diekspor dengan satu deklarasi.
  • File sumber ringkas dan metode utama instans [15] (Java 25) mengurangi upacara yang diperlukan untuk program kecil, yang membuat Java lebih mudah dipelajari dan lebih cepat untuk membuat prototipe.
  • Badan konstruktor fleksibel [16] (Java 25) memungkinkan Anda menjalankan pernyataan sebelum memanggil super(...) atau this(...), yang meningkatkan validasi dan inisialisasi.

Kinerja dan pengaktifan

Beberapa perubahan pada waktu proses meningkatkan laju pemrosesan, jejak memori, dan waktu mulai:

  • Header objek ringkas [17] (Java 25) mengurangi ukuran header objek pada platform 64-bit. Pengurangan ini menurunkan penggunaan timbunan dan dapat meningkatkan performa untuk beban kerja yang berat alokasi.
  • Berbagi data kelas (CDS) mengurangi waktu startup dengan memetakan kelas yang diarsipkan ke memori saat runtime. Arsip CDS default [18] (Java 12) dan arsip CDS dinamis [19] (Java 13) membuat fitur ini lebih mudah diadopsi tanpa pelatihan manual berjalan.
  • Pemuatan dan penautan kelas lebih awal [20] (Java 24), bersama dengan ergonomi baris perintah lebih awal [21] (Java 25) dan pemrofilan metode lebih awal [22] (Java 25), mempersingkat waktu mulai dan pemanasan dengan menggunakan kembali hasil kerja yang terekam dalam arsip aplikasi. Fitur-fitur ini adalah bagian dari upaya Project Leyden untuk membuat Java memulai lebih cepat.

Peningkatan ini sangat berharga terutama untuk beban kerja cloud-native dan nirserver, di mana waktu mulai yang cepat dan jejak memori yang kecil secara langsung menghasilkan penskalaan yang lebih baik serta biaya yang lebih rendah.

Pengumpulan sampah

Java 25 kapal dengan pengumpul sampah yang matang dan jeda rendah cocok untuk berbagai beban kerja:

  • ZGC [23] (Java 15) dan Shenandoah [24] (Java 15) adalah kolektor siap produksi yang dirancang untuk waktu jeda rendah pada timbunan besar.
  • G1GC tetap menjadi kolektor default dan terus menerima berbagai peningkatan, termasuk penguncian region [25] (Java 22) agar interaksi dengan kode native lebih lancar.
  • ZGC Generasional [26] (Java 21) meningkatkan efisiensi dengan mempertahankan generasi yang terpisah. Pada Java 23, ZGC berjalan dalam mode generasi secara default [27], dan mode non-generasi dihapus dalam Java 24.
  • Shenandoah Generasional [28] (Java 25) menambahkan mode generasional ke kolektor Shenandoah untuk meningkatkan throughput dan ketahanan saat berada di bawah tekanan memori.

JVM menetapkan default GC untuk kasus penggunaan rata-rata. Sesuaikan default ini dan pengaturan GC lainnya untuk mengoptimalkan throughput atau latensi sesuai dengan persyaratan aplikasi Anda.

Tip

Pengumpul sampah default dan banyak default JVM berbeda di seluruh versi Java, sehingga pengaturan yang disetel untuk Java 8 atau 11 mungkin tidak lagi optimal pada Java 25. Peluncur Perintah Azure untuk Java (jaz) membaca batas memori cgroup dan CPU kontainer dan menerapkan bendera JVM yang disesuaikan dengan versi dan lingkungan JDK secara otomatis.

Diagnostik dan pengamatan

Diagnostik ditingkatkan di berbagai rilis, baik pada bahasa maupun pada Java Flight Recorder (JFR):

  • Helpful NullPointerExceptions [29] (Java 14) menjelaskan dengan tepat variabel mana yang bernilai null, sehingga mempercepat proses penelusuran kesalahan.
  • streaming peristiwa JFR [30] (Java 14) memungkinkan alat memproses data pembuatan profil dan diagnostik secara terus-menerus, bukan dari file dump.
  • Pembuatan profil waktu CPU JFR [31] (Java 25) menambahkan pembuatan profil metode berbasis CPU eksperimental di Linux.
  • Pengambilan sampel kooperatif JFR [32] (Java 25) meningkatkan stabilitas pengambilan sampel stack.
  • Waktu dan pelacakan metode JFR [33] (Java 25) memungkinkan Anda mengatur waktu dan melacak metode tertentu tanpa memodifikasi kode aplikasi.

Keamanan dan kriptografi

Java 25 memperkuat postur keamanan platform, termasuk persiapan untuk dunia pasca-kuantum:

  • Edwards-Curve Digital Signature Algorithm (EdDSA) [34] (Java 15) menambahkan skema tanda tangan modern berkinerja tinggi.
  • API Mekanisme Enkapsulasi Kunci [35] (Java 21) menyediakan API standar untuk algoritma KEM.
  • Kriptografi tahan kuantum menambahkan implementasi standar mekanisme enkapsulasi kunci berbasis latensi modul (ML-KEM) [36] (Java 24) dan algoritma tanda tangan digital (ML-DSA) [37] (Java 24).
  • KEY Derivation Function API [38] (Java 25) menyediakan API standar untuk fungsi derivasi kunci.

Interoperabilitas asli

API Fungsi dan Memori Asing [39] (Java 22) menyediakan cara yang aman, efisien, dan berbasis Java sepenuhnya untuk memanggil pustaka asli dan mengakses memori asli. Ini adalah pengganti modern untuk Java Native Interface (JNI) yang mengurangi boilerplate dan meningkatkan keamanan.

Alat dan pustaka

Beberapa penambahan meningkatkan pengembangan sehari-hari dan mengurangi kebutuhan akan alat pihak ketiga:

  • Alat pengemasan (jpackage) [40] (Java 16) membuat alat penginstal dan paket asli untuk aplikasi Java.
  • Simple Web Server [41] (Java 18) menyediakan server HTTP file statis minimal untuk pembuatan prototipe dan pengujian.
  • Generator nomor pseudorandom yang ditingkatkan [42] (Java 17) menambahkan antarmuka dan implementasi baru untuk pembuatan angka acak.

Perubahan perilaku yang perlu direncanakan

Beberapa perubahan sejak Java 11 mengubah perilaku default, jadi tinjau sebelum Anda meningkatkan:

  • Enkapsulasi kuat terhadap internal JDK [43] (Java 17) memblokir akses refleksi ke sebagian besar API internal secara default. Kode atau pustaka yang menjangkau ke dalam sun.* atau paket internal lainnya mungkin memerlukan pembaruan.
  • UTF-8 secara default [44] (Java 18) menjadikan UTF-8 sebagai charset default untuk API Java standar. Aplikasi yang mengandalkan charset default khusus platform mungkin bereaksi berbeda.
  • Mendepresiasi finalisasi untuk dihapus [45] (Java 18) menandakan bahwa finalize() pada akhirnya akan dihapus. Migrasi ke try-with-resources atau java.lang.ref.Cleaner.
  • Bersiap untuk melarang pemuatan dinamis agen [46] (Java 21) memperingatkan ketika agen dimuat ke dalam JVM yang sedang berjalan. Beberapa alat pemantauan dan instrumentasi mungkin memerlukan perubahan konfigurasi.

Tip

Modernisasi aplikasi GitHub Copilot dapat membantu Anda menilai dan mengatasi perubahan perilaku ini secara otomatis saat Anda melakukan peningkatan versi.

Kontainer dan komputasi awan

Kemampuan JVM untuk mengenali kontainer, yang diperkenalkan untuk Docker dan runtime kontainer lainnya, terus disempurnakan. JVM membaca batasan CPU dan memori yang diatur oleh grup kontrol kontainer (cgroup) dan mengukur timbunan dan sumber daya lainnya yang sesuai. Dengan waktu startup yang lebih cepat, jejak memori yang lebih kecil, dan utas virtual, Java 25 sangat cocok untuk penerapan terkontainerisasi dan serverless di Azure.

Jika Anda menjalankan beban kerja Java pada kontainer Azure atau komputer virtual, Azure Command Launcher untuk Java (jaz) dapat menerapkan default JVM yang dioptimalkan cloud dan sesuai versi untuk Anda.

Langkah berikutnya

References

[1] Oracle Corporation, "JEP 444: Thread Virtual." (Online). Tersedia: https://openjdk.org/jeps/444.

[2] Oracle Corporation, "JEP 491: Sinkronisasi Utas Virtual tanpa Pinning." (Online). Tersedia: https://openjdk.org/jeps/491.

[3] Oracle Corporation, "JEP 506: Nilai Cakupan." (Online). Tersedia: https://openjdk.org/jeps/506.

[4] Oracle Corporation, "JEP 453: Konkurensi Terstruktur (Pratinjau)." (Online). Tersedia: https://openjdk.org/jeps/453.

[5] Oracle Corporation, "JEP 361: Beralih Ekspresi." (Online). Tersedia: https://openjdk.org/jeps/361.

[6] Oracle Corporation, "JEP 394: Pencocokan Pola untuk instanceof." (Online). Tersedia: https://openjdk.org/jeps/394.

[7] Oracle Corporation, "JEP 395: Records." (Online). Tersedia: https://openjdk.org/jeps/395.

[8] Oracle Corporation, "JEP 409: Kelas Yang Disegel." (Online). Tersedia: https://openjdk.org/jeps/409.

[9] Oracle Corporation, "JEP 378: Blok Teks." (Online). Tersedia: https://openjdk.org/jeps/378.

[10] Oracle Corporation, "JEP 441: Pencocokan pola untuk switch." (Online). Tersedia: https://openjdk.org/jeps/441.

[11] Oracle Corporation, "JEP 440: Pola Rekaman." (Online). Tersedia: https://openjdk.org/jeps/440.

[12] Oracle Corporation, "JEP 431: Koleksi Berurutan." (Online). Tersedia: https://openjdk.org/jeps/431.

[13] Oracle Corporation, "JEP 456: Variabel & Pola yang Tidak Disebutkan Namanya." (Online). Tersedia: https://openjdk.org/jeps/456.

[14] Oracle Corporation, "JEP 511: Deklarasi Impor Modul." (Online). Tersedia: https://openjdk.org/jeps/511.

[15] Oracle Corporation, "JEP 512: Berkas Sumber Ringkas dan Metode Main Instans." (Daring). Tersedia: https://openjdk.org/jeps/512.

[16] Oracle Corporation, "JEP 513: Badan Konstruktor Fleksibel." (Online). Tersedia: https://openjdk.org/jeps/513.

[17] Oracle Corporation, "JEP 519: Compact Object Headers." (Online). Tersedia: https://openjdk.org/jeps/519.

[18] Oracle Corporation, "JEP 341: Arsip CDS Bawaan." (Online). Tersedia: https://openjdk.org/jeps/341.

[19] Oracle Corporation, "JEP 350: Arsip CDS Dinamis." (Online). Tersedia: https://openjdk.org/jeps/350.

[20] Oracle Corporation, "JEP 483: Pemuatan dan Penautan Kelas Lebih Awal." (Online). Tersedia: https://openjdk.org/jeps/483.

[21] Oracle Corporation, "JEP 514: Ahead-of-Time Command-Line Ergonomics." (Online). Tersedia: https://openjdk.org/jeps/514.

[22] Oracle Corporation, "JEP 515: Pemrofilan Metode Ahead-of-Time." (Online). Tersedia: https://openjdk.org/jeps/515.

[23] Oracle Corporation, "JEP 377: ZGC: Pengumpul Sampah Low-Latency yang Dapat Diskalakan." (Online). Tersedia: https://openjdk.org/jeps/377.

[24] Oracle Corporation, "JEP 379: Shenandoah: Pengumpul Sampah dengan Waktu Jeda Rendah." (Online). Tersedia: https://openjdk.org/jeps/379.

[25] Oracle Corporation, "JEP 423: Penyematan Wilayah untuk G1." (Online). Tersedia: https://openjdk.org/jeps/423.

[26] Oracle Corporation, "JEP 439: Generational ZGC." (Online). Tersedia: https://openjdk.org/jeps/439.

[27] Oracle Corporation, "JEP 474: ZGC: Mode Generasional secara bawaan." (Online). Tersedia: https://openjdk.org/jeps/474.

[28] Oracle Corporation, "JEP 521: Generational Shenandoah." (Online). Tersedia: https://openjdk.org/jeps/521.

[29] Oracle Corporation, "JEP 358: Helpful NullPointerExceptions." (Online). Tersedia: https://openjdk.org/jeps/358.

[30] Oracle Corporation, "JEP 349: JFR Event Streaming." (Online). Tersedia: https://openjdk.org/jeps/349.

[31] Oracle Corporation, "JEP 509: JFR CPU-Time Profiling (Eksperimental)." (Online). Tersedia: https://openjdk.org/jeps/509.

[32] Oracle Corporation, "JEP 518: Pengambilan Sampel Koperasi JFR." (Online). Tersedia: https://openjdk.org/jeps/518.

[33] Oracle Corporation, "JEP 520: JFR Method Timing & Tracing." (Online). Tersedia: https://openjdk.org/jeps/520.

[34] Oracle Corporation, "JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA)." (Online). Tersedia: https://openjdk.org/jeps/339.

[35] Oracle Corporation, "JEP 452: API Mekanisme Enkapsulasi Kunci." (Online). Tersedia: https://openjdk.org/jeps/452.

[36] Oracle Corporation, "JEP 496: Quantum-Resistant Module-Lattice-Based Mekanisme Enkapulasi Kunci." (Online). Tersedia: https://openjdk.org/jeps/496.

[37] Oracle Corporation, "JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm." (Online). Tersedia: https://openjdk.org/jeps/497.

[38] Oracle Corporation, "JEP 510: Key Derivation Function API." (Online). Tersedia: https://openjdk.org/jeps/510.

[39] Oracle Corporation, "JEP 454: API Fungsi Eksternal & Memori." (Online). Tersedia: https://openjdk.org/jeps/454.

[40] Oracle Corporation, "JEP 392: Packaging Tool." (Online). Tersedia: https://openjdk.org/jeps/392.

[41] Oracle Corporation, "JEP 408: Simple Web Server." (Online). Tersedia: https://openjdk.org/jeps/408.

[42] Oracle Corporation, "JEP 356: Generator Bilangan Pseudoacak yang Disempurnakan." (Daring). Tersedia: https://openjdk.org/jeps/356.

[43] Oracle Corporation, "JEP 403: Enkapsulasi Kuat untuk Internal JDK." (Online). Tersedia: https://openjdk.org/jeps/403.

[44] Oracle Corporation, "JEP 400: UTF-8 Secara Bawaan." (Online). Tersedia: https://openjdk.org/jeps/400.

[45] Oracle Corporation, "JEP 421: Menghentikan Finalisasi untuk Penghapusan." (Online). Tersedia: https://openjdk.org/jeps/421.

[46] Oracle Corporation, "JEP 451: Bersiap untuk Melarang Pemuatan Dinamis Agen." (Online). Tersedia: https://openjdk.org/jeps/451.