JVM mengelola dua jenis memori, heap dan non-heap. Heap ditujukan untuk digunakan oleh pengembang, seperti disebutkan di atas, heap dibuat saat JVM dimulai; non-heap dicadangkan untuk JVM itu sendiri untuk menyimpan informasi kelas. Berbeda dengan heap, GC tidak akan melepaskan ruang saat runtime.
1. Tipe luapan memori
1. java.lang.OutOfMemoryError: ruang PermGen
JVM mengelola dua jenis memori, heap dan non-heap. Heap ditujukan untuk digunakan oleh pengembang, seperti disebutkan di atas, heap dibuat saat JVM dimulai; non-heap dicadangkan untuk JVM itu sendiri untuk menyimpan informasi kelas. Berbeda dengan heap, GC tidak akan melepaskan ruang saat runtime. Jika aplikasi web menggunakan toples pihak ketiga dalam jumlah besar atau aplikasi memiliki terlalu banyak file kelas dan pengaturan MaxPermSize ternyata kecil, melebihi batas juga akan menyebabkan memori memakan terlalu banyak dan menyebabkan overflow, atau kucing jantan akan tidak membersihkan bagian depan selama penerapan panas. Lingkungan yang dimuat hanya akan mengubah konteks ke lingkungan yang baru diterapkan, dan akan ada lebih banyak konten non-tumpukan.
Nama lengkap ruang PermGen adalah ruang Generasi Permanen, yang mengacu pada tempat penyimpanan permanen memori. Memori ini terutama digunakan oleh JVM untuk menyimpan informasi Kelas dan Meta Kelas akan ditempatkan di ruang PermGen ketika itu dimuat oleh Loader, dan menyimpan instance kelas (Instance) Area tumpukan berbeda, GC (Pengumpulan Sampah) tidak akan membersihkan ruang PermGen selama menjalankan program utama, jadi jika aplikasi Anda memiliki banyak KELAS, a Kesalahan ruang PermGen mungkin terjadi. Kesalahan semacam ini biasa terjadi ketika server web melakukan pra-kompilasi JSP. Jika APLIKASI WEB Anda menggunakan toples pihak ketiga dalam jumlah besar, dan ukurannya melebihi ukuran default jvm (4M), pesan kesalahan ini akan dihasilkan.
Contoh konfigurasi terbaik: (Setelah verifikasi sendiri, sejak menggunakan konfigurasi ini, Tomcat tidak pernah mati lagi)
atur JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
Di Linux, tambahkan sebaris kode seperti yang ditunjukkan dengan warna merah di Tomcathome/conf/catalina.sh: Anda dapat menambah memori Tomcat jvm, sehingga kecil kemungkinan terjadinya kelebihan memori!
# ----- Jalankan Perintah yang Diminta ---------------------------------------- -
JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"
# Bugzilla 37848: hanya menampilkan ini jika kita memiliki TTY
2. java.lang.OutOfMemoryError: Ruang Javaheap
Situasi pertama adalah pelengkap, dan masalah utama terjadi dalam situasi ini. Ruang defaultnya (yaitu -Xms) adalah 1/64 memori fisik, dan ruang maksimum (-Xmx) adalah 1/4 memori fisik. Jika sisa memori kurang dari 40%, JVM akan meningkatkan heap ke nilai yang ditetapkan oleh Xmx. Jika sisa memori melebihi 70%, JVM akan menurunkan heap ke nilai yang ditetapkan oleh Xms. Oleh karena itu, pengaturan Xmx dan Xms pada server umumnya harus diatur sama untuk menghindari penyesuaian ukuran tumpukan mesin virtual setelah setiap GC. Dengan asumsi memori fisik tidak terbatas, memori JVM maksimum bergantung pada sistem operasi. Umumnya, mesin 32-bit berkisar antara 1,5g dan 3g, sedangkan mesin 64-bit tidak memiliki batasan.
Catatan: Jika Xms melebihi nilai Xmx, atau jumlah nilai heap maksimum dan nilai maksimum non-heap melebihi batas maksimum memori fisik atau sistem operasi, server tidak akan dimulai.
Peran pengumpulan sampah GC
Frekuensi pemanggilan JVM GC masih sangat tinggi, dan pengumpulan sampah dilakukan dalam dua situasi utama:
Ketika thread aplikasi menganggur; yang lainnya adalah ketika tumpukan memori Java tidak mencukupi, GC akan terus dipanggil. Jika daur ulang berkelanjutan tidak dapat menyelesaikan masalah tumpukan memori yang tidak mencukupi, kesalahan kehabisan memori akan dilaporkan. Karena pengecualian ini bergantung pada lingkungan pengoperasian sistem, tidak mungkin memprediksi kapan hal ini akan terjadi.
Menurut mekanisme GC, berjalannya program akan menyebabkan perubahan pada lingkungan operasi sistem, sehingga meningkatkan kemungkinan terpicunya GC.
Untuk menghindari masalah ini, perancangan dan penulisan program harus menghindari penggunaan memori objek sampah dan overhead GC. Memanggil System.GC() secara eksplisit hanya dapat menyarankan bahwa JVM perlu mendaur ulang objek sampah di memori, tetapi tidak harus segera didaur ulang.
Salah satunya adalah tidak dapat menyelesaikan masalah kehabisan sumber daya memori, dan juga akan meningkatkan konsumsi GC.
2. Komposisi area memori JVM <BR>Cukup bicara tentang heap dan stack di java
Java membagi memori menjadi dua jenis: satu adalah memori tumpukan dan yang lainnya adalah memori tumpukan.
1. Variabel tipe dasar dan variabel referensi objek yang ditentukan dalam fungsi dialokasikan dalam memori tumpukan fungsi;
2. Memori heap digunakan untuk menyimpan objek dan array yang baru. Ketika suatu variabel didefinisikan dalam suatu fungsi (blok kode), Java mengalokasikan ruang memori untuk variabel pada stack melepaskannya secara otomatis. Menghapus ruang memori yang dialokasikan untuk variabel; memori yang dialokasikan di heap dikelola oleh pengumpul sampah otomatis dari mesin virtual Java tidak perlu diberitahukan kepada compiler terlebih dahulu, karena berada di dalam Memori yang dialokasikan secara dinamis pada saat runtime. Kerugiannya adalah memori harus dialokasikan secara dinamis saat runtime, dan kecepatan aksesnya lambat;
Keuntungan dari stack adalah kecepatan aksesnya lebih cepat dibandingkan dengan heap. Kerugiannya adalah ukuran dan umur data yang disimpan dalam stack harus bersifat deterministik dan tidak fleksibel.
Java heap dibagi menjadi tiga area: Baru, Lama dan Permanen
GC memiliki dua utas:
Objek yang baru dibuat dialokasikan ke area Baru. Ketika area tersebut terisi, maka akan dipindahkan ke area Lama oleh thread bantu GC. Ketika area Lama juga terisi, thread utama GC akan dipicu untuk melintasi semua objek di dalamnya memori tumpukan. Luas area Lama sama dengan Xmx dikurangi -Xmn
Penyesuaian tumpukan penyimpanan tumpukan Java: Parameternya adalah +UseDefaultStackSize -Xss256K, yang berarti bahwa setiap thread dapat menerapkan ruang tumpukan 256k. Setiap thread memiliki Stacknya sendiri.
3. Cara mengatur memori virtual di JVM <BR>Tip: Di JVM, jika 98% waktunya digunakan untuk GC dan ukuran Heap yang tersedia kurang dari 2%, pesan pengecualian ini akan ditampilkan.
Tip: Ukuran Heap maksimum tidak boleh melebihi 80% dari memori fisik yang tersedia. Umumnya, opsi -Xms dan -Xmx harus disetel ke nilai yang sama, dan -Xmn harus 1/4 dari nilai -Xmx.
Tip: Memori awal yang dialokasikan oleh JVM ditentukan oleh -Xms, dan defaultnya adalah 1/64 dari memori fisik; memori maksimum yang dialokasikan oleh JVM ditentukan oleh -Xmx, dan defaultnya adalah 1/4 dari memori fisik ingatan.
Secara default, ketika memori heap bebas kurang dari 40%, JVM akan meningkatkan heap hingga batas maksimum -Xmx; ketika memori heap bebas lebih besar dari 70%, JVM akan mengurangi heap hingga batas minimum -Xms. Oleh karena itu, server biasanya menyetel -Xms dan -Xmx agar sama untuk menghindari penyesuaian ukuran heap setelah setiap GC.
Tip: Dengan asumsi bahwa memori fisik tidak terbatas, nilai maksimum memori JVM memiliki hubungan yang baik dengan sistem operasi.
Sederhananya, meskipun prosesor 32-bit memiliki ruang memori yang dapat dikontrol sebesar 4GB, sistem operasi tertentu akan memberlakukan batasan.
Batasan ini umumnya 2GB-3GB (secara umum, 1,5G-2G pada sistem Windows dan 2G-3G pada sistem Linux), dan tidak akan ada batasan untuk prosesor di atas 64bit.
Catatan: Jika Xms melebihi nilai Xmx, atau jumlah nilai heap maksimum dan nilai maksimum non-heap melebihi batas maksimum memori fisik atau sistem operasi, server tidak akan dimulai.
Tip: Atur NewSize dan MaxNewSize menjadi sama, dan ukuran "baru" tidak boleh lebih besar dari setengah "lama". Alasannya adalah jika area lama tidak cukup besar, GC "utama" akan sering terpicu , yang sangat mengurangi kinerja.
JVM menggunakan -XX:PermSize untuk menetapkan nilai awal memori non-heap. Defaultnya adalah 1/64 memori fisik;
Ukuran memori non-heap maksimum diatur oleh XX:MaxPermSize. Defaultnya adalah 1/4 dari memori fisik.
Solusi: Atur ukuran Heap secara manual
Ubah TOMCAT_HOME/bin/catalina.bat
Tambahkan baris berikut di atas "echo "Using CATALINA_BASE: $CATALINA_BASE"":
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
4. Gunakan alat pemeriksaan kinerja untuk menemukan kebocoran memori:
Alat JProfiler terutama digunakan untuk memeriksa dan melacak kinerja sistem (terbatas pada pengembangan Java). JProfiler dapat memantau operasi dan kinerja JVM dengan terus memantau penggunaan memori sistem, pengumpulan sampah, status pengoperasian thread, dan cara lainnya kapan saja.
1. Memori server aplikasi terisi secara tidak wajar dalam waktu yang lama. Memori sering kali terisi pada level tinggi dan sulit dipulihkan ke level rendah.