Kami mendapatkan "java.lang.OutOfMemoryError : unable to create new native Thread
"pada VM RAM 8GB setelah 32k utas (ps -eLF | grep -c java)
Namun "top" and "free -m" shows 50% free memory available
,. JDk 64 bit dan dicoba dengan HotSpot dan JRockit. Server memiliki Linux 2.6.18
Kami juga mencoba OS stack size (ulimit -s)
tweaker dan proses max (ulimit -u) batas, limit.conf meningkat tetapi semuanya sia-sia.
Kami juga mencoba hampir semua kemungkinan kombinasi ukuran heap, menjaganya tetap rendah, tinggi, dll.
Script yang kami gunakan untuk menjalankan aplikasi adalah
/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties
Terima kasih balasannya.
Kami telah mencoba mengedit /etc/security/limits.conf dan ulimit tetapi masih tetap sama
[root@jboss02 ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 72192
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 72192
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
java
out-of-memory
Deepak Tewani
sumber
sumber
ExecutorService
) sebagai gantinya.Jawaban:
Ini bukan masalah memori meskipun nama pengecualian sangat menyarankannya, tetapi masalah sumber daya sistem operasi. Anda kehabisan utas asli, yaitu berapa banyak utas yang diizinkan oleh sistem operasi untuk digunakan JVM Anda.
Ini adalah masalah yang jarang terjadi, karena Anda jarang membutuhkan sebanyak itu. Apakah Anda memiliki banyak pemijahan benang tanpa syarat di mana benang seharusnya tetapi tidak selesai?
Anda dapat mempertimbangkan untuk menulis ulang menggunakan Callable / Runnables di bawah kendali Executor jika memungkinkan. Ada banyak eksekutor standar dengan berbagai perilaku yang dapat dikontrol kode Anda dengan mudah.
(Ada banyak alasan mengapa jumlah utas dibatasi, tetapi bervariasi dari sistem operasi ke sistem operasi)
sumber
Saya mengalami masalah yang sama selama uji beban, alasannya adalah karena JVM tidak dapat membuat utas Java baru lebih lanjut. Di bawah ini adalah kode sumber JVM
Dalam kasus saya, Jboss membuat terlalu banyak utas, untuk melayani permintaan, tetapi semua utas diblokir. Karena itu, JVM kehabisan thread juga dengan memori (setiap thread menyimpan memori, yang tidak dirilis, karena setiap thread diblokir).
Menganalisis java thread dumps mengamati hampir 61K utas diblokir oleh salah satu metode kami, yang menyebabkan masalah ini. Di bawah ini adalah bagian dari Thread dump
sumber
Sepertinya OS Anda tidak mengizinkan jumlah utas yang Anda coba buat, atau Anda mencapai beberapa batasan di JVM. Terutama jika itu adalah angka bulat seperti 32k, batas satu jenis atau lainnya adalah penyebabnya.
Apakah Anda yakin Anda benar-benar membutuhkan 32k utas? Sebagian besar bahasa modern memiliki semacam dukungan untuk kumpulan utas yang dapat digunakan kembali - Saya yakin Java juga memiliki sesuatu (seperti
ExecutorService
, seperti yang disebutkan pengguna Jesper). Mungkin Anda dapat meminta utas dari kumpulan seperti itu, daripada membuat yang baru secara manual.sumber
Saya akan merekomendasikan untuk juga melihat Ukuran Tumpukan Benang dan melihat apakah Anda mendapatkan lebih banyak utas yang dibuat. Ukuran Thread Stack default untuk JRockit 1.5 / 1.6 adalah 1 MB untuk VM 64-bit di OS Linux. Utas 32K akan membutuhkan sejumlah besar memori fisik dan virtual untuk memenuhi persyaratan ini.
Cobalah untuk mengurangi Ukuran Stack menjadi 512 KB sebagai titik awal dan lihat apakah itu membantu membuat lebih banyak utas untuk aplikasi Anda. Saya juga merekomendasikan untuk menjelajahi penskalaan horizontal, misalnya membagi pemrosesan aplikasi Anda di lebih banyak mesin fisik atau virtual.
Saat menggunakan VM 64-bit, batas sebenarnya akan bergantung pada ketersediaan memori fisik dan virtual OS serta parameter penyetelan OS seperti ulimitc. Saya juga merekomendasikan artikel berikut sebagai referensi:
OutOfMemoryError: tidak dapat membuat utas asli baru - Masalah Demystified
sumber
Jika jvm dimulai melalui systemd, mungkin ada maxTasks per batas proses (tugas sebenarnya berarti utas) di beberapa OS linux.
Anda dapat memeriksa ini dengan menjalankan "status layanan" dan memeriksa apakah ada batas maxTasks. Jika ada, Anda dapat menghapusnya dengan mengedit /etc/systemd/system.conf, menambahkan konfigurasi: DefaultTasksMax = infinity
sumber
Saya memiliki masalah yang sama karena proses hantu yang tidak muncul saat menggunakan top in bash. Ini mencegah JVM menelurkan lebih banyak utas.
Bagi saya, itu diselesaikan ketika mendaftar semua proses java dengan jps (cukup jalankan
jps
di shell Anda) dan bunuh mereka secara terpisah menggunakankill -9 pid
perintah bash untuk setiap proses hantu.Ini mungkin membantu dalam beberapa skenario.
sumber
Anda memiliki kesempatan untuk menghadapi
java.lang.OutOfMemoryError: Unable to create new native thread
kapan pun JVM meminta utas baru dari OS. Setiap kali OS yang mendasarinya tidak dapat mengalokasikan utas asli baru, OutOfMemoryError ini akan dilempar. Batas pasti untuk utas asli sangat bergantung pada platform, oleh karena itu disarankan untuk mencari tahu batas tersebut dengan menjalankan pengujian yang mirip dengan contoh tautan di bawah ini. Namun secara umum penyebab situasijava.lang.OutOfMemoryError: Unable to create new native thread
melalui tahapan sebagai berikut:Referensi: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
sumber
Untuk menemukan proses mana yang membuat utas coba:
Saya biasanya mengarahkan output ke file dan menganalisis file secara offline (apakah jumlah utas untuk setiap proses seperti yang diharapkan atau tidak)
sumber
Jika Job Anda gagal karena OutOfMemmory pada node, Anda dapat mengubah jumlah max map dan reducer dan JVM memilih untuk masing-masing node. mapred.child.java.opts (default adalah 200Xmx) biasanya harus ditingkatkan berdasarkan perangkat keras spesifik node data Anda.
Tautan ini mungkin bisa membantu ... tolong periksa
sumber
konfigurasi JBoss Anda memiliki beberapa masalah, /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms dan Xmx membatasi penggunaan memori JBoss Anda, ke nilai yang dikonfigurasi, jadi dari 8Gb yang Anda miliki server hanya menggunakan 512M + beberapa tambahan untuk tujuannya sendiri, tingkatkan jumlah itu, ingatlah untuk meninggalkan beberapa gratis untuk OS dan hal-hal lain yang berjalan di sana dan mungkin Anda menjalankannya meskipun ada kode yang tidak menyenangkan. Memperbaiki kode juga akan menyenangkan, jika Anda bisa.
sumber
Kesalahan ini dapat muncul karena dua alasan berikut:
Tidak ada ruang di memori untuk menampung utas baru.
Jumlah utas melebihi batas Sistem Operasi.
Saya ragu bahwa jumlah utas telah melebihi batas untuk proses java
Jadi kemungkinan besar masalahnya adalah karena memori. Satu hal yang perlu dipertimbangkan adalah
Solusi yang mungkin adalah mengurangi memori heap atau meningkatkan ukuran ram secara keseluruhan
sumber
Saya memiliki masalah yang sama dan ternyata itu adalah penggunaan yang tidak tepat dari API java. Saya menginisialisasi pembangun dalam metode pemrosesan batch yang seharusnya tidak dimulai lebih dari sekali.
Pada dasarnya saya melakukan sesuatu seperti:
ketika saya seharusnya melakukan ini:
sumber
Pertama-tama saya tidak akan menyalahkan OS / VM sebanyak itu .. melainkan pengembang yang menulis kode yang membuat begitu banyak Thread . Pada dasarnya di suatu tempat di kode Anda (atau pihak ke-3) banyak utas dibuat tanpa kontrol .
Tinjau stacktraces / kode dengan hati-hati dan kendalikan jumlah utas yang dibuat. Biasanya aplikasi Anda tidak memerlukan thread dalam jumlah besar, jika memang masalahnya berbeda.
sumber