Baru-baru ini saya mengalami kesalahan ini dalam aplikasi web saya:
java.lang.OutOfMemoryError: Ruang PermGen
Ini adalah aplikasi khas Hibernate / JPA + IceFaces / JSF yang berjalan pada Tomcat 6 dan JDK 1.6. Rupanya ini dapat terjadi setelah memindahkan aplikasi beberapa kali.
Apa yang menyebabkannya dan apa yang bisa dilakukan untuk menghindarinya? Bagaimana cara saya memperbaiki masalah?
Jawaban:
Solusinya adalah menambahkan flag-flag ini ke baris perintah JVM ketika Tomcat dimulai:
Anda dapat melakukannya dengan mematikan layanan tomcat, kemudian masuk ke direktori Tomcat / bin dan menjalankan tomcat6w.exe. Di bawah tab "Java", tambahkan argumen ke kotak "Java Options". Klik "OK" dan kemudian restart layanan.
Jika Anda mendapatkan kesalahan , layanan yang ditentukan tidak ada sebagai layanan yang diinstal, Anda harus menjalankan:
di mana servicename adalah nama server seperti yang dilihat di services.msc
Sumber: komentar orx pada Eric's Agile Answers .
sumber
Anda sebaiknya mencoba
-XX:MaxPermSize=128M
daripada-XX:MaxPermGen=128M
.Saya tidak bisa mengatakan dengan tepat penggunaan kumpulan memori ini, tetapi itu ada hubungannya dengan jumlah kelas yang dimuat ke JVM. (Dengan demikian mengaktifkan pembongkaran kelas untuk kucing jantan dapat menyelesaikan masalah.) Jika aplikasi Anda menghasilkan dan mengkompilasi kelas yang sedang berjalan, lebih mungkin membutuhkan kumpulan memori yang lebih besar dari standar.
sumber
Server aplikasi PermGen kesalahan yang terjadi setelah beberapa penyebaran kemungkinan besar disebabkan oleh referensi yang dipegang oleh kontainer ke dalam classloader aplikasi lama Anda. Misalnya, menggunakan kelas tingkat log kustom akan menyebabkan referensi ditahan oleh classloader server aplikasi. Anda dapat mendeteksi kebocoran antar-kelas ini dengan menggunakan alat analisis JVM (JDK6 +) modern seperti jmap dan jhat untuk melihat kelas mana yang terus diadakan di aplikasi Anda, dan mendesain ulang atau menghilangkan penggunaannya. Tersangka yang biasa adalah basis data, penebang, dan pustaka tingkat dasar kerangka kerja lainnya.
Lihat kebocoran Classloader: pengecualian "java.lang.OutOfMemoryError: PermGen space" yang ditakuti , dan terutama posting tindak lanjutnya .
sumber
Kesalahan umum yang dilakukan orang adalah berpikir bahwa tumpukan ruang dan ruang permgen adalah sama, yang sama sekali tidak benar. Anda bisa memiliki banyak ruang yang tersisa di tumpukan tetapi masih dapat kehabisan memori di permgen.
Penyebab umum OutofMemory di PermGen adalah ClassLoader. Setiap kali kelas dimuat ke JVM, semua meta datanya, bersama dengan Classloader, disimpan di area PermGen dan mereka akan menjadi sampah yang dikumpulkan ketika Classloader yang memuatnya siap untuk pengumpulan sampah. Dalam Kasus Classloader memiliki kebocoran kehabisan memori dari semua kelas yang dimuat olehnya akan tetap ada dalam memori dan menyebabkan memori keluar setelah Anda mengulanginya beberapa kali. Contoh klasik adalah Java.lang.OutOfMemoryError: PermGen Space di Tomcat .
Sekarang ada dua cara untuk mengatasi ini:
1. Temukan penyebab Memory Leak atau jika ada kebocoran memori.
2. Meningkatkan ukuran Ruang PermGen dengan menggunakan param
-XX:MaxPermSize
dan JVM-XX:PermSize
.Anda juga dapat memeriksa 2 Solusi Java.lang.OutOfMemoryError di Java untuk detail lebih lanjut.
sumber
-XX:MaxPermSize and -XX:PermSize
?? Saya tidak dapat menemukancatalina.bat
. Versi tomcat saya adalah5.5.26
.Gunakan parameter baris perintah
-XX:MaxPermSize=128m
untuk Sun JVM (jelas menggantikan 128 untuk ukuran apa pun yang Anda butuhkan).sumber
Coba
-XX:MaxPermSize=256m
dan jika terus, coba-XX:MaxPermSize=512m
sumber
XX:MaxPermSize=1024m
:)Saya menambahkan
-XX: MaxPermSize = 128m
(Anda dapat melakukan percobaan yang paling berhasil) ke Argumen VM karena saya menggunakan ide gerhana. Di sebagian besar JVM, PermSize default adalah sekitar 64MB yang kehabisan memori jika ada terlalu banyak kelas atau sejumlah besar String dalam proyek.Untuk gerhana, itu juga dijelaskan pada jawaban .
LANGKAH 1 : Klik dua kali pada tomcat server di Servers Tab
LANGKAH 2 : Buka luncurkan Conf dan tambahkan
-XX: MaxPermSize = 128m
ke akhir argumentasi VM yang ada .sumber
Saya telah membenturkan kepala saya terhadap masalah ini saat menggunakan dan tidak menggunakan aplikasi web yang rumit juga, dan berpikir saya akan menambahkan penjelasan dan solusi saya.
Ketika saya menyebarkan aplikasi di Apache Tomcat, ClassLoader baru dibuat untuk aplikasi itu. ClassLoader kemudian digunakan untuk memuat semua kelas aplikasi, dan saat tidak bekerja, semuanya seharusnya hilang dengan baik. Namun, pada kenyataannya itu tidak sesederhana itu.
Satu atau lebih dari kelas yang dibuat selama kehidupan aplikasi web memiliki referensi statis yang, di suatu tempat sepanjang garis, referensi ClassLoader. Karena referensi awalnya statis, jumlah pengumpulan sampah tidak akan membersihkan referensi ini - ClassLoader, dan semua kelas yang dimuat, ada di sini untuk tinggal.
Dan setelah beberapa penukaran, kami menemukan OutOfMemoryError.
Sekarang ini telah menjadi masalah yang cukup serius. Saya bisa memastikan bahwa Tomcat di-restart setelah setiap pemindahan, tetapi itu menurunkan seluruh server, bukan hanya aplikasi yang dipindah, yang seringkali tidak layak.
Jadi alih-alih saya telah mengumpulkan solusi dalam kode, yang berfungsi pada Apache Tomcat 6.0. Saya belum menguji pada server aplikasi lain, dan harus menekankan bahwa ini sangat mungkin tidak berfungsi tanpa modifikasi pada server aplikasi lain .
Saya juga ingin mengatakan bahwa secara pribadi saya benci kode ini, dan bahwa tidak ada yang harus menggunakan ini sebagai "perbaikan cepat" jika kode yang ada dapat diubah untuk menggunakan metode shutdown dan pembersihan yang tepat . Satu-satunya saat ini harus digunakan adalah jika ada perpustakaan eksternal yang bergantung pada kode Anda (Dalam kasus saya, itu adalah klien RADIUS) yang tidak menyediakan sarana untuk membersihkan referensi statisnya sendiri.
Bagaimanapun, lanjutkan dengan kode. Ini harus disebut pada titik di mana aplikasi tidak dipekerjakan - seperti metode penghancuran servlet atau (pendekatan yang lebih baik) metode konteksDestroyed ServletContextListener.
sumber
The
java.lang.OutOfMemoryError: PermGen
pesan ruang menunjukkan bahwa daerah Generation Tetap di memori habis.Aplikasi Java apa pun diizinkan untuk menggunakan memori dalam jumlah terbatas. Jumlah persis memori aplikasi tertentu Anda dapat menggunakan ditentukan selama startup aplikasi.
Memori Java dipisahkan menjadi beberapa wilayah yang dapat dilihat pada gambar berikut:
Metaspace: Ruang memori baru lahir
JDK 8 HotSpot JVM sekarang menggunakan memori asli untuk representasi metadata kelas dan disebut Metaspace; mirip dengan Oracle JRockit dan IBM JVM.
Berita baiknya adalah itu berarti tidak ada lagi
java.lang.OutOfMemoryError: PermGen
masalah ruang dan tidak perlu lagi Anda menyetel dan memantau ruang memori ini lagi menggunakan Java_8_Download atau lebih tinggi.sumber
1) Meningkatkan Ukuran Memori PermGen
Hal pertama yang bisa dilakukan adalah membuat ukuran ruang tumpukan generasi permanen lebih besar. Ini tidak dapat dilakukan dengan argumen JVM –Xms (atur ukuran heap awal) dan –Xmx (atur ukuran heap maksimum), karena seperti yang disebutkan, ruang heap generasi permanen sepenuhnya terpisah dari ruang Java Heap biasa, dan argumen ini di atur ruang untuk ruang heap Java biasa ini. Namun, ada argumen serupa yang dapat digunakan (setidaknya dengan jvms Sun / OpenJDK) untuk membuat ukuran generasi permanen lebih besar:
Default adalah 64m.
2) Aktifkan Sweeping
Cara lain untuk mengatasinya adalah dengan membiarkan kelas diturunkan sehingga PermGen Anda tidak pernah habis:
Hal-hal seperti itu berhasil bagiku di masa lalu. Namun satu hal, ada trade off kinerja yang signifikan dalam menggunakannya, karena sapuan permgen akan membuat seperti 2 permintaan tambahan untuk setiap permintaan yang Anda buat atau sesuatu di sepanjang garis itu. Anda harus menyeimbangkan penggunaan Anda dengan pengorbanan.
Anda dapat menemukan detail kesalahan ini.
http://faisalbhagat.blogspot.com/2014/09/java-outofmemoryerror-permgen.html
sumber
Atau, Anda dapat beralih ke JRockit yang menangani permgen berbeda dari jvm sun. Biasanya memiliki kinerja yang lebih baik.
http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html
sumber
java.lang.OutOfMemoryError: There is insufficient native memory
sebagai gantinya.Saya punya masalah yang kita bicarakan di sini, skenario saya adalah eclipse-helios + tomcat + jsf dan apa yang Anda lakukan adalah membuat penerapan aplikasi sederhana untuk tomcat. Saya menunjukkan masalah yang sama di sini, menyelesaikannya sebagai berikut.
Dalam gerhana pergi ke tab server klik dua kali pada server terdaftar dalam kasus saya kucing jagoan 7.0, itu membuka file server saya informasi pendaftaran umum. Pada bagian "Informasi Umum" klik pada tautan "Buka konfigurasi peluncuran" , ini membuka pelaksanaan opsi server di tab Argumen di argumen VM ditambahkan di akhir dua entri ini
dan siap.
sumber
Jawaban paling sederhana hari ini adalah menggunakan Java 8.
Ini tidak lagi menyimpan memori khusus untuk ruang PermGen, memungkinkan memori PermGen untuk bergabung dengan kumpulan memori biasa.
Perlu diingat bahwa Anda harus menghapus semua
-XXPermGen...=...
parameter startup JVM non-standar jika Anda tidak ingin Java 8 mengeluh bahwa mereka tidak melakukan apa-apa.sumber
Di area teks Opsi Java tambahkan baris ini:
sumber
Perm gen space error terjadi karena penggunaan ruang besar daripada jvm menyediakan ruang untuk mengeksekusi kode.
Solusi terbaik untuk masalah ini dalam sistem operasi UNIX adalah mengubah beberapa konfigurasi pada file bash. Langkah-langkah berikut menyelesaikan masalah.
Jalankan perintah
gedit .bashrc
pada terminal.Buat
JAVA_OTPS
variabel dengan nilai berikut:Simpan file bash. Jalankan perintah exec bash di terminal. Mulai ulang server.
Saya harap pendekatan ini akan mengatasi masalah Anda. Jika Anda menggunakan versi Java lebih rendah dari 8 masalah ini kadang-kadang terjadi. Tetapi jika Anda menggunakan Java 8 masalah tidak pernah terjadi.
sumber
Meningkatkan ukuran Generasi Permanen atau mengubah parameter GC TIDAK akan membantu jika Anda memiliki kebocoran memori nyata. Jika aplikasi Anda atau pustaka pihak ketiga yang digunakannya, kebocoran kelas loader satu-satunya solusi nyata dan permanen adalah menemukan kebocoran ini dan memperbaikinya. Ada sejumlah alat yang dapat membantu Anda, salah satunya adalah Plumbr , yang baru saja merilis versi baru dengan kemampuan yang diperlukan.
sumber
Juga jika Anda menggunakan log4j di aplikasi web Anda, periksa paragraf ini di dokumentasi log4j .
Tampaknya jika Anda menggunakan
PropertyConfigurator.configureAndWatch("log4j.properties")
, Anda menyebabkan kebocoran memori saat Anda menganggur dari aplikasi web Anda.sumber
Saya memiliki kombinasi Hibernate + Eclipse RCP, mencoba menggunakan
-XX:MaxPermSize=512m
dan-XX:PermSize=512m
dan sepertinya berfungsi untuk saya.sumber
Setel
-XX:PermSize=64m -XX:MaxPermSize=128m
. Kemudian Anda juga dapat mencoba meningkatkanMaxPermSize
. Semoga ini akan berhasil. Hal yang sama berlaku untuk saya. Pengaturan hanyaMaxPermSize
tidak berhasil untuk saya.sumber
Saya mencoba beberapa jawaban dan satu-satunya yang akhirnya berhasil adalah konfigurasi untuk plugin kompiler di pom:
semoga yang ini membantu.
sumber
jrockitmenyelesaikan ini untukku juga; Namun, saya perhatikan bahwa waktu restart servlet jauh lebih buruk, jadi sementara itu lebih baik dalam produksi, itu semacam hambatan dalam pengembangan.
sumber
Konfigurasi memori tergantung pada sifat aplikasi Anda.
Apa yang sedang kamu lakukan?
Berapa jumlah transaksi yang harus dilakukan?
Berapa banyak data yang Anda muat?
dll.
dll.
dll
Mungkin Anda dapat membuat profil aplikasi Anda dan mulai membersihkan beberapa modul dari aplikasi Anda.
Tomcat memiliki penyebaran panas tetapi menghabiskan memori. Coba mulai ulang wadah Anda sesekali. Anda juga perlu mengetahui jumlah memori yang diperlukan untuk berjalan dalam mode produksi, ini sepertinya waktu yang tepat untuk penelitian itu.
sumber
Mereka mengatakan bahwa rev terbaru dari Tomcat (6.0.28 atau 6.0.29) menangani tugas pemindahan servlet jauh lebih baik.
sumber
Saya mengalami masalah yang persis sama, tetapi sayangnya tidak ada solusi yang disarankan yang bekerja untuk saya. Masalahnya tidak terjadi selama penyebaran, dan saya tidak melakukan penyebaran panas.
Dalam kasus saya, masalah terjadi setiap kali pada titik yang sama selama eksekusi aplikasi web saya, saat menghubungkan (via hibernate) ke database.
Tautan ini (juga disebutkan sebelumnya) memang menyediakan bagian dalam yang cukup untuk menyelesaikan masalah. Memindahkan driver jdbc- (mysql) dari WEB-INF dan masuk ke folder jre / lib / ext / tampaknya telah menyelesaikan masalah. Ini bukan solusi yang ideal, karena meningkatkan ke JRE yang lebih baru akan mengharuskan Anda untuk menginstal ulang driver. Kandidat lain yang dapat menyebabkan masalah serupa adalah log4j, jadi Anda mungkin ingin memindahkannya juga
sumber
Langkah pertama dalam kasus tersebut adalah memeriksa apakah GC diizinkan untuk menurunkan kelas dari PermGen. Standar JVM agak konservatif dalam hal ini - kelas dilahirkan untuk hidup selamanya. Jadi, sekali dimuat, kelas tetap berada dalam memori bahkan jika tidak ada kode yang menggunakannya lagi. Ini bisa menjadi masalah ketika aplikasi membuat banyak kelas secara dinamis dan kelas yang dihasilkan tidak diperlukan untuk periode yang lebih lama. Dalam kasus seperti itu, memungkinkan JVM untuk menurunkan definisi kelas dapat membantu. Ini dapat dicapai dengan menambahkan hanya satu parameter konfigurasi ke skrip startup Anda:
Secara default ini disetel ke false dan untuk mengaktifkannya, Anda perlu secara eksplisit mengatur opsi berikut dalam opsi Java. Jika Anda mengaktifkan CMSClassUnloadingEnabled, GC juga akan menyapu PermGen dan menghapus kelas yang tidak lagi digunakan. Perlu diingat bahwa opsi ini hanya akan berfungsi ketika UseConcMarkSweepGC juga diaktifkan menggunakan opsi di bawah ini. Jadi ketika menjalankan ParallelGC atau, Tuhan melarang, Serial GC, pastikan Anda telah mengatur GC Anda ke CMS dengan menentukan:
sumber
Menugaskan Tomcat lebih banyak memori BUKAN solusi yang tepat.
Solusi yang benar adalah dengan melakukan pembersihan setelah konteksnya dihancurkan dan diciptakan kembali (penyebaran panas). Solusinya adalah menghentikan kebocoran memori.
Jika Tomcat / Webapp Server memberi tahu Anda bahwa gagal untuk membatalkan registrasi driver (JDBC), maka batalkan registrasi. Ini akan menghentikan kebocoran memori.
Anda dapat membuat ServletContextListener dan mengkonfigurasinya di web.xml Anda. Berikut ini adalah contoh ServletContextListener:
Dan di sini Anda mengkonfigurasinya di web.xml Anda:
sumber
"Mereka" salah karena saya menjalankan 6.0.29 dan memiliki masalah yang sama bahkan setelah mengatur semua opsi. Seperti yang dikatakan Tim Howland di atas, opsi-opsi ini hanya menunda yang tak terhindarkan. Mereka memungkinkan saya untuk memindahkan 3 kali sebelum memukul kesalahan daripada setiap kali saya memindahkan.
sumber
Jika Anda mendapatkan ini di IDE gerhana, bahkan setelah mengatur parameter
--launcher.XXMaxPermSize
,,-XX:MaxPermSize
dll, masih jika Anda mendapatkan kesalahan yang sama, kemungkinan besar adalah bahwa gerhana menggunakan versi kereta JRE yang akan diinstal oleh beberapa aplikasi pihak ketiga dan diatur ke default. Versi kereta ini tidak mengambil parameter PermSize dan jadi apa pun yang Anda atur, Anda masih terus mendapatkan kesalahan memori ini. Jadi, di eclipse.ini Anda tambahkan parameter berikut:Pastikan juga Anda mengatur JRE default di preferensi di gerhana ke versi java yang benar.
sumber
Satu-satunya cara yang berhasil bagi saya adalah dengan JVM JRockit. Saya memiliki MyEclipse 8.6.
Tumpukan JVM menyimpan semua objek yang dihasilkan oleh program Java yang sedang berjalan. Java menggunakan
new
operator untuk membuat objek, dan memori untuk objek baru dialokasikan pada heap saat dijalankan. Pengumpulan sampah adalah mekanisme untuk secara otomatis membebaskan memori yang terkandung oleh objek yang tidak lagi dirujuk oleh program.sumber
Saya mengalami masalah serupa. Tambang saya adalah JDK 7 + Maven 3.0.2 + Struts 2.0 + proyek berbasis ketergantungan ketergantungan GUICE Google.
Setiap kali saya mencoba menjalankan
mvn clean package
perintah, itu menunjukkan kesalahan berikut dan "BUILD FAILURE" terjadiSaya mencoba semua tips dan trik yang bermanfaat di atas tetapi sayangnya tidak ada yang berhasil untuk saya. Apa yang berhasil bagi saya dijelaskan langkah demi langkah di bawah ini: =>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
elemen baru dan kemudian<argLine>
sub elemen yang lulus-Xmx512m -XX:MaxPermSize=256m
seperti yang ditunjukkan di bawah ini =><configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration>
Semoga bisa membantu, selamat pemrograman :)
sumber