Manajemen memori Java

Catatan

Azure Spring Apps adalah nama baru untuk layanan Azure Spring Cloud. Meskipun layanan memiliki nama baru, Anda akan melihat nama lama di beberapa tempat untuk sementara saat kami berupaya memperbarui aset seperti cuplikan layar, video, dan diagram.

Artikel ini berlaku untuk: ✔️ Basic/Standard ✔️ Enterprise

Artikel ini menjelaskan berbagai konsep yang terkait dengan manajemen memori Java untuk membantu Anda memahami perilaku aplikasi Java yang dihosting di Azure Spring Apps.

Model memori Java

Memori aplikasi Java memiliki beberapa bagian, dan ada berbagai cara untuk membagi bagian. Artikel ini membahas memori Java sebagai dibagi menjadi memori tumpukan, memori non-tumpukan, dan memori langsung.

Memori timbunan

Memori timbunan menyimpan semua instans dan array kelas. Setiap komputer virtual Java (JVM) hanya memiliki satu area timbunan, yang dibagikan di antara utas.

Spring Boot Actuator dapat mengamati nilai memori timbunan. Spring Boot Actuator mengambil nilai timbunan sebagai bagian jvm.memory.used/committed/maxdari . Untuk informasi selengkapnya, lihat bagian jvm.memory.used/committed/max di Alat untuk memecahkan masalah memori.

Memori tumpukan dibagi menjadi generasi muda dan generasi tua. Istilah-istilah ini dijelaskan dalam daftar berikut, bersama dengan istilah terkait.

  • Generasi muda: semua objek baru dialokasikan dan berusia di generasi muda.

    • Ruang Eden: objek baru dialokasikan di ruang Eden.
    • Ruang yang selamat: objek akan dipindahkan dari Eden ke ruang yang selamat setelah bertahan hidup satu siklus pengumpulan sampah. Ruang penyintas dapat dibagi menjadi dua bagian: s1 dan s2.
  • Generasi lama: juga disebut ruang penyewaan. Objek yang tetap berada di ruang penyintas untuk waktu yang lama akan dipindahkan ke generasi lama.

Sebelum Java 8, bagian lain yang disebut generasi permanen juga merupakan bagian dari timbunan. Dimulai dengan Java 8, generasi permanen digantikan oleh metaspace dalam memori non-heap.

Memori non-tumpuk

Memori non-tumpukan dibagi menjadi bagian-bagian berikut:

  • Bagian dari memori non-tumpukan yang menggantikan generasi permanen (atau permGen) dimulai dengan Java 8. Spring Boot Actuator mengamati bagian ini dan mengambilnya sebagai bagian jvm.memory.used/committed/maxdari . Dengan kata lain, jvm.memory.used/committed/max adalah jumlah memori timbunan dan bagian mantan permGen dari memori non-tumpuk. Generasi permanen sebelumnya terdiri dari bagian-bagian berikut:

    • Metaspace, yang menyimpan definisi kelas yang dimuat oleh pemuat kelas.
    • Ruang kelas terkompresi, yang untuk penunjuk kelas terkompresi.
    • Cache kode, yang menyimpan kode asli yang dikompilasi oleh JIT.
  • Memori lain seperti tumpukan utas, yang tidak diamati oleh Spring Boot Actuator.

Memori langsung

Memori langsung adalah memori asli yang dialokasikan oleh java.nio.DirectByteBuffer, yang digunakan dalam pustaka pihak ketiga seperti nio dan gzip.

Spring Boot Actuator tidak mengamati nilai memori langsung.

Diagram berikut ini meringkas model memori Java yang dijelaskan di bagian sebelumnya.

Diagram yang memperlihatkan model memori Java.

Pengumpulan sampah Java

Ada tiga istilah mengenai Java Garbage Collection (GC): "Minor GC", "Major GC", dan "Full GC". Istilah-istilah ini tidak didefinisikan dengan jelas dalam spesifikasi JVM. Di sini, kami menganggap "Major GC" dan "Full GC" setara.

GC kecil dilakukan ketika ruang Eden penuh. Ini menghilangkan semua benda mati pada generasi muda dan memindahkan objek hidup ke dari ruang Eden ke s1 ruang yang selamat, atau dari s1 ke s2.

GC penuh atau GC utama melakukan pengumpulan sampah di seluruh tumpukan. Full GC juga dapat mengumpulkan bagian-bagian seperti metaspace dan memori langsung, yang hanya dapat dibersihkan dengan GC penuh.

Ukuran timbunan maksimum memengaruhi frekuensi GC kecil dan GC penuh. Metaspace maksimum dan ukuran memori langsung maksimum memengaruhi GC penuh.

Ketika Anda mengatur ukuran tumpukan maksimum ke nilai yang lebih rendah, pengumpulan sampah terjadi lebih sering, yang memperlambat aplikasi sedikit, tetapi lebih membatasi penggunaan memori. Ketika Anda mengatur ukuran tumpukan maksimum ke nilai yang lebih tinggi, pengumpulan sampah terjadi lebih jarang, yang dapat menciptakan lebih banyak risiko kehabisan memori (OOM). Untuk informasi selengkapnya, lihat bagian Jenis masalah di luar memori dari Masalah mulai ulang Aplikasi yang disebabkan oleh masalah di luar memori.

Metaspace dan memori langsung hanya dapat dikumpulkan dengan GC penuh. Ketika metaspace atau memori langsung penuh, GC penuh akan terjadi.

Konfigurasi memori Java

Bagian berikut menjelaskan aspek penting dari konfigurasi memori Java.

Kontainerisasi Java

Aplikasi di Azure Spring Apps berjalan di lingkungan kontainer. Untuk informasi selengkapnya, lihat Membuat kontainer aplikasi Java Anda.

Opsi JVM penting

Anda dapat mengonfigurasi ukuran maksimum setiap bagian memori dengan menggunakan opsi JVM. Anda dapat mengatur opsi JVM dengan menggunakan perintah Azure CLI atau melalui portal Azure. Untuk informasi selengkapnya, lihat bagian Ubah konfigurasi untuk memperbaiki masalah Alat untuk memecahkan masalah memori.

Daftar berikut ini menjelaskan opsi JVM:

  • Konfigurasi ukuran timbunan

    • -Xms mengatur ukuran tumpukan awal menurut nilai absolut.
    • -Xmx mengatur ukuran timbunan maksimum menurut nilai absolut.
    • -XX:InitialRAMPercentage mengatur ukuran timbunan awal berdasarkan persentase ukuran timbunan/ukuran memori aplikasi.
    • -XX:MaxRAMPercentage mengatur ukuran timbunan maksimum dengan persentase ukuran timbunan/ukuran memori aplikasi.
  • Konfigurasi ukuran memori langsung

    • -XX:MaxDirectMemorySize mengatur ukuran memori langsung maksimum menurut nilai absolut. Untuk informasi selengkapnya, lihat MaxDirectMemorySize dalam dokumentasi Oracle.
  • Konfigurasi ukuran metaspace

    • -XX:MaxMetaspaceSize mengatur ukuran metaspace maksimum menurut nilai absolut.

Ukuran memori maksimum default

Bagian berikut menjelaskan bagaimana ukuran memori maksimum default diatur.

Ukuran timbunan maksimum default

Azure Spring Apps mengatur ukuran memori timbunan maksimum default menjadi sekitar 50%-80% memori aplikasi untuk aplikasi Java. Secara khusus, Azure Spring Apps menggunakan pengaturan berikut:

  • Jika memori < aplikasi 1 GB, ukuran timbunan maksimum default akan menjadi 50% memori aplikasi.
  • Jika 1 GB <= memori < aplikasi 2 GB, ukuran timbunan maksimum default akan menjadi 60% memori aplikasi.
  • Jika 2 GB <= memori < aplikasi 3 GB, ukuran timbunan maksimum default akan menjadi 70% memori aplikasi.
  • Jika 3 GB <= memori aplikasi, ukuran timbunan maksimum default akan menjadi 80% memori aplikasi.

Ukuran memori langsung maksimum default

Ketika ukuran memori langsung maksimum tidak diatur menggunakan opsi JVM, JVM secara otomatis mengatur ukuran memori langsung maksimum ke nilai yang dikembalikan oleh Runtime.getRuntime.maxMemory(). Nilai ini kira-kira sama dengan ukuran memori timbunan maksimum. Untuk informasi selengkapnya, lihat file VM.java JDK 8.

Tata letak penggunaan memori

Ukuran timbunan dipengaruhi oleh throughput Anda. Pada dasarnya, saat mengonfigurasi, Anda dapat menyimpan ukuran timbunan maksimum default, yang meninggalkan memori yang wajar untuk bagian lain.

Ukuran metaspace tergantung pada kompleksitas kode Anda, seperti jumlah kelas.

Ukuran memori langsung tergantung pada throughput Anda dan penggunaan pustaka pihak ketiga seperti nio dan gzip.

Daftar berikut menjelaskan sampel tata letak memori umum untuk aplikasi 2 GB. Anda dapat merujuk ke daftar ini untuk mengonfigurasi pengaturan ukuran memori Anda.

  • Total Memori (2048M)
  • Memori timbunan: Xmx adalah 1433,6M (70% dari total memori). Nilai referensi penggunaan memori harian adalah 1200M.
    • Generasi muda
      • Ruang penyintas (S0, S1)
      • Ruang Eden
    • Generasi lama
  • Memori non-tumpuk
    • Bagian yang diamati (diamati oleh Spring Boot Actuator)
      • Metaspace: nilai referensi penggunaan harian adalah 50M-256M
      • Cache kode
      • Ruang kelas terkompresi
    • Bagian yang tidak diamati (tidak diamati oleh Spring Boot Actuator): nilai referensi penggunaan harian adalah 150M-250M.
      • Tumpukan utas
      • GC, simbol internal, dan lainnya
  • Memori langsung: nilai referensi penggunaan harian adalah 10M-200M.

Diagram berikut menunjukkan informasi yang sama. Angka berwarna abu-abu adalah nilai referensi penggunaan memori harian.

Diagram tata letak memori umum untuk aplikasi 2 GB.

Secara keseluruhan, saat mengonfigurasi ukuran memori maksimum, Anda harus mempertimbangkan penggunaan setiap bagian dalam memori, dan jumlah semua ukuran maksimum tidak boleh melebihi total memori yang tersedia.

Java OOM

OOM berarti aplikasi kehabisan memori. Ada dua konsep berbeda: OOM kontainer dan OOM JVM. Untuk informasi selengkapnya, lihat Masalah mulai ulang aplikasi yang disebabkan oleh masalah di luar memori.

Lihat juga