Saya menulis aplikasi Swing sisi klien (desainer font grafis) di Java 5 . Baru-baru ini, saya mengalami java.lang.OutOfMemoryError: Java heap space
kesalahan karena saya tidak konservatif dalam penggunaan memori. Pengguna dapat membuka file dalam jumlah tidak terbatas, dan program ini menyimpan objek yang dibuka di memori. Setelah penelitian cepat saya menemukan Ergonomi di Java Virtual Machine 5.0 dan yang lain mengatakan pada mesin Windows JVM default max heap size as 64MB
.
Dengan situasi ini, bagaimana saya harus mengatasi kendala ini?
Saya dapat meningkatkan ukuran heap maks menggunakan opsi baris perintah ke java, tapi itu akan membutuhkan mencari tahu RAM yang tersedia dan menulis beberapa program peluncuran atau skrip. Selain itu, peningkatan hingga beberapa hingga pada akhirnya tidak menyingkirkan masalah tersebut.
Saya bisa menulis ulang beberapa kode saya untuk tetap mempertahankan objek ke sistem file (menggunakan database adalah hal yang sama) untuk membebaskan memori. Itu bisa berhasil, tapi mungkin itu juga banyak pekerjaan.
Jika Anda bisa mengarahkan saya ke detail ide di atas atau beberapa alternatif seperti memori virtual otomatis, memperluas ukuran tumpukan secara dinamis , itu akan menjadi hebat.
sumber
Jawaban:
Pada akhirnya Anda selalu memiliki tumpukan maksimum yang terbatas untuk digunakan, apa pun platform yang Anda jalankan. Di Windows 32 bit ini ada di sekitar
2GB
(tidak secara khusus menumpuk tetapi jumlah total memori per proses). Kebetulan Java memilih untuk membuat default lebih kecil (mungkin sehingga programmer tidak dapat membuat program yang memiliki alokasi memori yang hilang tanpa mengalami masalah ini dan harus memeriksa dengan tepat apa yang mereka lakukan).Jadi ini mengingat ada beberapa pendekatan yang dapat Anda ambil untuk menentukan jumlah memori yang Anda butuhkan atau untuk mengurangi jumlah memori yang Anda gunakan. Salah satu kesalahan umum dengan sampah yang dikumpulkan bahasa seperti Java atau C # adalah untuk tetap mencari referensi ke objek yang tidak lagi Anda gunakan, atau mengalokasikan banyak objek saat Anda bisa menggunakannya kembali . Selama objek memiliki referensi kepada mereka, mereka akan terus menggunakan ruang tumpukan karena pengumpul sampah tidak akan menghapusnya.
Dalam hal ini Anda dapat menggunakan profiler memori Java untuk menentukan metode apa dalam program Anda yang mengalokasikan sejumlah besar objek dan kemudian menentukan apakah ada cara untuk memastikan mereka tidak lagi direferensikan, atau untuk tidak mengalokasikannya di tempat pertama. Salah satu opsi yang saya gunakan di masa lalu adalah "JMP" http://www.khelekore.org/jmp/ .
Jika Anda menentukan bahwa Anda mengalokasikan objek-objek ini untuk suatu alasan dan Anda perlu mencari referensi (tergantung pada apa yang Anda lakukan ini mungkin terjadi), Anda hanya perlu meningkatkan ukuran tumpukan maksimum ketika Anda memulai program. Namun, begitu Anda melakukan profil memori dan memahami bagaimana objek Anda dialokasikan, Anda harus memiliki ide yang lebih baik tentang berapa banyak memori yang Anda butuhkan.
Secara umum jika Anda tidak dapat menjamin bahwa program Anda akan berjalan dalam sejumlah memori terbatas (mungkin tergantung pada ukuran input) Anda akan selalu mengalami masalah ini. Hanya setelah melelahkan semua ini Anda akan perlu melihat ke dalam objek caching ke disk dll. Pada titik ini Anda harus memiliki alasan yang sangat baik untuk mengatakan "Saya perlu Xgb memori" untuk sesuatu dan Anda tidak dapat mengatasinya dengan meningkatkan algoritma atau pola alokasi memori Anda. Secara umum ini biasanya hanya akan menjadi kasus untuk algoritma yang beroperasi pada dataset besar (seperti database atau beberapa program analisis ilmiah) dan kemudian teknik seperti caching dan memori dipetakan IO menjadi berguna.
sumber
Jalankan Java dengan opsi baris perintah
-Xmx
, yang menetapkan ukuran maksimum heap.Lihat di sini untuk detailnya .
sumber
Anda dapat menentukan per proyek berapa banyak tumpukan ruang yang diinginkan proyek Anda
Berikut ini untuk Eclipse Helios / Juno / Kepler :
Klik kanan mouse
lalu tambahkan ini
sumber
Meningkatkan ukuran tumpukan bukan "memperbaiki" itu adalah "plester", 100% sementara. Ini akan crash lagi di tempat lain. Untuk menghindari masalah ini, tulis kode kinerja tinggi.
sumber
Peringatan besar ---- di kantor saya, kami menemukan (pada beberapa mesin windows) kami tidak dapat mengalokasikan lebih dari 512m untuk heap Java. Ini ternyata disebabkan oleh produk anti-virus Kaspersky yang diinstal pada beberapa mesin tersebut. Setelah mencopot pemasangan produk AV itu, kami menemukan bahwa kami dapat mengalokasikan setidaknya 1,6gb, yaitu
-Xmx1600m
(m wajib jika tidak akan menyebabkan kesalahan lain "Tumpukan awal yang terlalu kecil") berfungsi.Tidak tahu apakah ini terjadi dengan produk AV lainnya, tetapi mungkin ini terjadi karena program AV menyimpan blok memori kecil di setiap ruang alamat, sehingga mencegah alokasi tunggal yang sangat besar.
sumber
Argumen VM bekerja untuk saya di gerhana. Jika Anda menggunakan eclipse versi 3.4, lakukan hal berikut
pergi ke
Run --> Run Configurations -->
kemudian pilih proyek di bawah maven build -> lalu pilih tab "JRE" -> lalu masukkan-Xmx1024m
.Atau Anda bisa melakukannya
Run --> Run Configurations --> select the "JRE" tab -->
lalu masuk -Xmx1024m
Ini harus meningkatkan tumpukan memori untuk semua build / proyek. Ukuran memori di atas adalah 1 GB. Anda dapat mengoptimalkan seperti yang Anda inginkan.
sumber
Ya, dengan
-Xmx
Anda dapat mengonfigurasi lebih banyak memori untuk JVM Anda. Untuk memastikan bahwa Anda tidak membocorkan atau membuang memori. Ambil tumpukan sampah dan gunakan Eclipse Memory Analyzer untuk menganalisis konsumsi memori Anda.sumber
Saya ingin menambahkan rekomendasi dari pemotretan masalah oracle artikel .
Pengecualian di utas thread_name: java.lang.OutOfMemoryError: Java heap space
Kemungkinan penyebab:
Masalah konfigurasi sederhana , di mana ukuran tumpukan yang ditentukan tidak mencukupi untuk aplikasi.
Aplikasi secara tidak sengaja memegang referensi ke objek , dan ini mencegah objek dari pengumpulan sampah.
Penggunaan finalizer yang berlebihan .
Setelah pengumpulan sampah , objek diantrikan untuk finalisasi , yang terjadi di lain waktu. finalizers dieksekusi oleh thread daemon yang melayani antrian finalisasi. Jika utas finalizer tidak dapat mengikuti antrian finalisasi, maka Java heap dapat terisi dan jenis pengecualian OutOfMemoryError ini akan dibuang.
Satu skenario yang dapat menyebabkan situasi ini adalah ketika aplikasi membuat utas prioritas tinggi yang menyebabkan antrian finalisasi meningkat pada tingkat yang lebih cepat daripada laju di mana benang finalizer sedang melayani antrian itu.
sumber
Ikuti langkah-langkah di bawah ini:
Buka
catalina.sh
dari tomcat / bin.Ubah JAVA_OPTS ke
Mulai ulang tomcat Anda
sumber
Saya membaca di tempat lain bahwa Anda dapat mencoba - menangkap java.lang.OutOfMemoryError dan di blok tangkap, Anda dapat membebaskan semua sumber daya yang Anda tahu mungkin menggunakan banyak memori, menutup koneksi dan sebagainya, lalu melakukan
System.gc()
kembali coba apa pun kamu akan lakukan.Cara lain adalah ini walaupun, saya tidak tahu apakah ini akan berhasil, tetapi saya sedang menguji apakah ini akan berfungsi pada aplikasi saya.
Idenya adalah untuk melakukan pengumpulan Sampah dengan memanggil System.gc () yang dikenal untuk meningkatkan memori bebas. Anda dapat terus memeriksa ini setelah kode yang menelan memori dijalankan.
sumber
Cara mudah untuk menyelesaikannya
OutOfMemoryError
di java adalah meningkatkan ukuran heap maksimum dengan menggunakan opsi JVM-Xmx512M
, ini akan segera menyelesaikan OutOfMemoryError Anda. Ini adalah solusi pilihan saya ketika saya mendapatkan OutOfMemoryError di Eclipse, Maven atau ANT sambil membangun proyek karena berdasarkan pada ukuran proyek Anda dapat dengan mudah kehabisan Memori.Berikut adalah contoh peningkatan ukuran heap maksimum JVM, Juga lebih baik untuk menjaga -Xmx ke -Xms ransum 1: 1 atau 1: 1,5 jika Anda mengatur ukuran heap dalam aplikasi java Anda.
export JVM_ARGS="-Xms1024m -Xmx1024m"
Tautan Referensi
sumber
Secara default untuk pengembangan, JVM menggunakan ukuran kecil dan konfigurasi kecil untuk fitur terkait kinerja lainnya. Tetapi untuk produksi Anda dapat menyetel misalnya (Selain itu konfigurasi khusus Application Server dapat ada) -> (Jika masih tidak cukup memori untuk memenuhi permintaan dan tumpukan sudah mencapai ukuran maksimum, OutOfMemoryError akan terjadi)
Sebagai contoh: Pada Platform linux untuk pengaturan mode produksi lebih disukai.
Setelah mengunduh dan mengkonfigurasi server dengan cara ini http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/
1. buat file setenv.sh pada folder / opt / tomcat / bin /
2.Buka dan tulis params ini untuk mengatur mode yang lebih disukai.
3.
service tomcat restart
sumber
Saya telah menghadapi masalah yang sama dari ukuran tumpukan java.
Saya punya dua solusi jika Anda menggunakan java 5 (1.5).
cukup instal jdk1.6 dan buka preferensi eclipse dan atur jalur jre jav1 1.6 seperti yang telah Anda instal.
Periksa argumen VM Anda dan biarkan apa pun itu. cukup tambahkan satu baris di bawah ini dari semua argumen yang ada dalam argumen VM sebagai -Xms512m -Xmx512m -XX: MaxPermSize = ... m (192m).
Saya pikir itu akan berhasil ...
sumber
Jika Anda perlu memantau penggunaan memori Anda saat runtime,
java.lang.management
paket penawaranMBeans
yang dapat digunakan untuk memantau kumpulan memori di VM Anda (misalnya, ruang eden, generasi bertenor dll), dan juga perilaku pengumpulan sampah.Ruang heap gratis yang dilaporkan oleh MBeans ini akan sangat bervariasi tergantung pada perilaku GC, terutama jika aplikasi Anda menghasilkan banyak objek yang nantinya merupakan GC-ed. Salah satu pendekatan yang mungkin adalah memantau ruang tumpukan kosong setelah setiap GC penuh, yang mungkin dapat Anda gunakan untuk membuat keputusan membebaskan memori dengan benda-benda yang ada.
Pada akhirnya, taruhan terbaik Anda adalah membatasi retensi memori Anda sejauh mungkin sementara kinerja tetap dapat diterima. Seperti komentar sebelumnya dicatat, memori selalu terbatas, tetapi aplikasi Anda harus memiliki strategi untuk mengatasi kelelahan memori.
sumber
Perhatikan bahwa jika Anda memerlukan ini dalam situasi penerapan, pertimbangkan untuk menggunakan Java WebStart (dengan versi "ondisk", bukan yang satu jaringan - mungkin di Java 6u10 dan yang lebih baru) karena memungkinkan Anda untuk menentukan berbagai argumen untuk JVM dalam tanda silang. cara platform.
Kalau tidak, Anda akan memerlukan peluncur khusus sistem operasi yang menetapkan argumen yang Anda butuhkan.
sumber
Jika masalah ini terjadi di Wildfly 8 dan JDK1.8, maka kita perlu menentukan pengaturan MaxMetaSpace daripada pengaturan PermGen.
Sebagai contoh kita perlu menambahkan konfigurasi di bawah ini di file setenv.sh dari wildfly.
JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"
Untuk informasi lebih lanjut, silakan periksa Wildfly Heap Issue
sumber
Mengenai netbeans, Anda bisa mengatur ukuran heap maks untuk menyelesaikan masalah.
Pergi ke 'Jalankan', lalu -> 'Atur Konfigurasi Proyek' -> 'Kustomisasi' -> 'jalankan' dari jendela yang muncul -> 'Opsi VM' -> isi '-Xms2048m -Xmx2048m' .
sumber
Jika Anda terus mengalokasikan & menyimpan referensi ke objek, Anda akan mengisi jumlah memori yang Anda miliki.
Salah satu opsi adalah melakukan file transparan tutup & buka ketika mereka beralih tab (Anda hanya menyimpan pointer ke file, dan ketika pengguna beralih tab, Anda menutup & membersihkan semua objek ... itu akan membuat perubahan file lebih lambat ... tapi ...), dan mungkin hanya menyimpan 3 atau 4 file di memori.
Hal lain yang harus Anda lakukan adalah, ketika pengguna membuka file, memuatnya, dan mencegat OutOfMemoryError, kemudian (karena tidak mungkin untuk membuka file) tutup file itu, bersihkan objeknya dan peringatkan pengguna bahwa ia harus menutup yang tidak digunakan. file.
Gagasan Anda untuk memperluas memori virtual secara dinamis tidak menyelesaikan masalah, karena mesin terbatas pada sumber daya, jadi Anda harus berhati-hati & menangani masalah memori (atau setidaknya, berhati-hatilah dengan mereka).
Beberapa petunjuk yang pernah saya lihat dengan kebocoran memori adalah:
-> Ingatlah bahwa jika Anda memasukkan sesuatu ke dalam koleksi dan kemudian melupakannya, Anda masih memiliki referensi yang kuat untuk itu, jadi batalkan koleksi itu, bersihkan atau lakukan sesuatu dengannya ... jika tidak, Anda akan menemukan kebocoran memori sulit ditemukan.
-> Mungkin, menggunakan koleksi dengan referensi yang lemah (weakhashmap ...) dapat membantu dengan masalah memori, tetapi Anda harus berhati-hati dengannya, karena Anda mungkin menemukan bahwa objek yang Anda cari telah dikumpulkan.
-> Gagasan lain yang saya temukan adalah untuk mengembangkan koleksi persisten yang disimpan pada objek basis data yang paling sedikit digunakan dan dimuat secara transparan. Ini mungkin akan menjadi pendekatan terbaik ...
sumber
Jika semuanya gagal, selain meningkatkan ukuran heap maks, cobalah juga meningkatkan ukuran swap. Untuk Linux, seperti yang sekarang, instruksi yang relevan dapat ditemukan di https://linuxize.com/post/create-a-linux-swap-file/ .
Ini dapat membantu jika Anda misalnya mengkompilasi sesuatu yang besar di platform yang disematkan.
sumber