"Java.lang.OutOfMemoryError: नया देशी धागा बनाने में असमर्थ"


124

हम "java.lang.OutOfMemoryError : unable to create new native Thread32k थ्रेड्स (ps -eLF | grep -c java) के बाद 8GB RAM VM पर " प्राप्त कर रहे हैं "

हालांकि, "top" and "free -m" shows 50% free memory available। JDk 64 बिट है और हॉटस्पॉट और JRockit दोनों के साथ प्रयास किया गया है। सेवर में लिनक्स 2.6.18 है

हमने OS stack size (ulimit -s)ट्वीकिंग और अधिकतम प्रक्रिया (अलिमिट -यू) की सीमा, सीमा को बढ़ाने की कोशिश की ।

इसके अलावा, हमने ढेर आकार संयोजन के लगभग सभी संभव प्रयास किए, इसे कम, उच्च आदि रखते हुए।

हम जिस स्क्रिप्ट का उपयोग एप्लिकेशन को चलाने के लिए करते हैं वह है

/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties

उत्तर के लिए धन्यवाद।

हमने /etc/security/limits.conf और ulimit के संपादन की कोशिश की है लेकिन फिर भी वही है

[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

11
ऑपरेटिंग सिस्टम में थ्रेड्स की संख्या पर सीमा होती है जो आप बना सकते हैं। आप 32k से अधिक थ्रेड्स क्यों बना रहे हैं? आपके सिस्टम में सबसे अधिक संभावना नहीं है कि हजारों प्रोसेसर कोर हैं, इतने सारे धागे उपयोगी नहीं हैं। ExecutorServiceइसके बजाय थ्रेड पूल ( ) का उपयोग करें।
जेस्पर

उत्तर के लिए धन्यवाद। हम एक ओपन सोर्स लाइब्रेरी का उपयोग कर रहे हैं और परीक्षण को लोड करने की कोशिश कर रहे हैं। कोई भी खुला स्रोत पुस्तकालय इतने सारे धागे पैदा कर रहा है। लेकिन जो मुझे समझ नहीं आ रहा है, वह यह है कि जब "टॉप" 50% फ्री मेमोरी दिखा रहा है तो आउटऑफमेरी एरर क्यों।
दीपक तेवानी

ओपन सोर्स लाइब्रेरी जिसे हम ICE4j लाइब्रेरी में इस्तेमाल कर रहे हैं
दीपक तेवानी

11
OutOfMemoryError जरूरी नहीं कि ढेर स्थान, या "सामान्य" रैम का मतलब है, समाप्त हो गया था। इस मामले में यह स्पष्ट है कि ओएस के कारण विफलता एक अतिरिक्त धागा आवंटित करने के लिए संसाधन नहीं थे। 50% मुक्त मेमोरी होना इस विशेष विफलता के लिए अप्रासंगिक है।
आंद्रेज डोयले

1
नए सूत्र बनाने के लिए आवश्यक अन्य संसाधन क्या हैं। हम इस धारणा के अधीन थे कि यदि हम रैम बढ़ाते हैं, तो हम अधिक थ्रेड बनाने में सक्षम हो सकते हैं। कृपया हमारा मार्गदर्शन करें
दीपक तिवानी

जवाबों:


80

यह एक स्मृति समस्या नहीं है भले ही अपवाद नाम अत्यधिक ऐसा सुझाता है, लेकिन एक ऑपरेटिंग सिस्टम संसाधन समस्या। आप मूल थ्रेड्स से बाहर चल रहे हैं, यानी ऑपरेटिंग सिस्टम आपके थ्रेड को कितने JVM का उपयोग करने की अनुमति देगा।

यह एक असामान्य समस्या है, क्योंकि आपको शायद ही कभी कई की आवश्यकता होती है। क्या आपके पास बहुत सी बिना शर्त धागा स्पॉनिंग है जहाँ धागे चाहिए लेकिन खत्म नहीं होते हैं?

यदि संभव हो तो किसी एक्जिक्यूटर के नियंत्रण में आप कॉल करने योग्य / रनवेब का उपयोग करने पर पुनर्लेखन पर विचार कर सकते हैं। विभिन्न व्यवहार के साथ बहुत सारे मानक निष्पादक हैं जिन्हें आपका कोड आसानी से नियंत्रित कर सकता है।

(थ्रेड्स की संख्या सीमित होने के कई कारण हैं, लेकिन वे ऑपरेटिंग सिस्टम से ऑपरेटिंग सिस्टम तक भिन्न होते हैं)


उत्तर के लिए धन्यवाद। हम एक ओपन सोर्स लाइब्रेरी ICE4j का उपयोग कर रहे हैं और परीक्षण को लोड करने की कोशिश कर रहे हैं। कठबोली हम ओएस में थ्रेड्स की सीमा बढ़ाते हैं जब हम जानते हैं कि सर्वर पर 50% मेमोरी शेष है।
दीपक तेवानी

संभवतः, लेकिन मुझे लगता है कि यह आपकी मदद नहीं करेगा। यदि आप लोड परीक्षण करते समय संसाधनों से बाहर निकलते हैं तो आपको यह नियंत्रित करने में सक्षम होना चाहिए कि आपके आवेदन में क्या होता है। आपके पास एक बार में 32000 धागे क्यों सक्रिय हैं?
थोरबजोर्न रेवन एंडरसन

हम 11K ग्राहक बना रहे हैं जो यूडीपी सॉकेट्स पर डेटा पढ़ने, लिखने के लिए 32 K थ्रेड का उपयोग करते हैं। इन 32 K थ्रेड्स में से 10K थ्रेड जिंदा धागे हैं जो सॉकेट को खुला रखने के लिए उपयोग किए जाते हैं
दीपक तेवानी

मेरा मानना ​​है कि यह समस्या आधुनिक वेब सर्वरों में हल हो गई है। Udp पैकेट को ढीला कर सकता है - किसी भी कारण से आप वेब सर्वर का उपयोग नहीं करते हैं?
थोरबजोर्न रेवन एंडरसन

7
क्योंकि OutOfMemory अपवाद को OutOfResources नाम दिया जाना चाहिए था। ऑपरेटिंग सिस्टम आपको आवश्यक संसाधन प्रदान नहीं कर सकता है। (और यह पता चला है कि मैं नहीं जानता था ice4j)
रावन एंडरसन

14

मुझे लोड परीक्षण के दौरान एक ही मुद्दे का सामना करना पड़ा, इसका कारण यह है कि जेवीएम आगे एक नया जावा धागा बनाने में असमर्थ है। नीचे JVM स्रोत कोड है

if (native_thread->osthread() == NULL) {    
// No one should hold a reference to the 'native_thread'.    
    delete native_thread;   
if (JvmtiExport::should_post_resource_exhausted()) {      
    JvmtiExport::post_resource_exhausted(        
        JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | 
        JVMTI_RESOURCE_EXHAUSTED_THREADS, 
        "unable to create new native thread");    
    } THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "unable to create new native thread");  
} Thread::start(native_thread);`

मूल कारण: JVMTI इस अपवाद को तब फेंकता है जब JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR (संसाधन समाप्त हो जाना (मतलब थकावट समाप्त होना)) या JVMTI_RESOURCE_EXHAEDED_THREADS (थ्रेड्स समाप्त हो जाना)।

मेरे मामले में, Jboss अनुरोध की सेवा करने के लिए बहुत सारे थ्रेड्स बना रहा है, लेकिन सभी थ्रेड्स अवरुद्ध हैं। इस वजह से, जेवीएम थ्रेड्स के साथ-साथ मेमोरी के साथ समाप्त हो जाता है (प्रत्येक थ्रेड मेमोरी रखता है, जो जारी नहीं किया गया है, क्योंकि प्रत्येक थ्रेड अवरुद्ध है)।

विश्लेषण किए गए जावा थ्रेड डंप ने लगभग 61K थ्रेड्स को हमारी एक विधि द्वारा अवरुद्ध कर दिया है, जो इस समस्या का कारण बन रहा है। नीचे थ्रेड डंप का हिस्सा है

"SimpleAsyncTaskExecutor-16562" #38070 prio=5 os_prio=0 tid=0x00007f9985440000 nid=0x2ca6 waiting for monitor entry [0x00007f9d58c2d000]
   java.lang.Thread.State: BLOCKED (on object monitor)

कैसे विधि अवरुद्ध था? कभी नहीं लौट रहा?
Thorbjørn रावन एंडरसन

8

यह संभावना है कि आपका OS आपके द्वारा बनाए जा रहे थ्रेड्स की संख्या की अनुमति नहीं देता है, या आप JVM में कुछ सीमाएं मार रहे हैं। खासकर अगर यह 32k के रूप में एक ऐसी गोल संख्या है, तो एक तरह की सीमा या किसी अन्य की संभावना बहुत ही अपराधी है।

क्या आप वाकई 32k धागे की जरूरत है? अधिकांश आधुनिक भाषाओं में पुन: प्रयोज्य धागों के पूल के लिए कुछ प्रकार का समर्थन है - मुझे यकीन है कि जावा में भी कुछ है (जैसे ExecutorService, उपयोगकर्ता जेसपर उल्लेख किया गया है)। शायद आप मैन्युअल रूप से नए बनाने के बजाय, ऐसे पूल से धागे का अनुरोध कर सकते हैं।


1
उत्तर के लिए धन्यवाद हम एक ओपन सोर्स लाइब्रेरी ICE4j का उपयोग कर रहे हैं और परीक्षण को लोड करने की कोशिश कर रहे हैं। कठबोली हम ओएस में थ्रेड्स की सीमा बढ़ाते हैं जब हम जानते हैं कि सर्वर पर 50% मेमोरी शेष है।
दीपक तेवानी

1
हम 11K ग्राहक बना रहे हैं जो यूडीपी सॉकेट्स पर डेटा पढ़ने, लिखने के लिए 32 K थ्रेड का उपयोग करते हैं। इन 32 K थ्रेड्स में से 10K थ्रेड जिंदा धागे हैं जो सॉकेट को खुला रखने के लिए उपयोग किए जाते हैं
दीपक तेवानी

7

मैं थ्रेड स्टैक आकार को देखने और यह देखने की भी सिफारिश करूंगा कि क्या आपको अधिक थ्रेड बनाए गए हैं। लिनक्स ओएस पर 64-बिट वीएम के लिए JRockit 1.5 / 1.6 के लिए डिफ़ॉल्ट थ्रेड स्टैक आकार 1 एमबी है। इस आवश्यकता को पूरा करने के लिए 32K थ्रेड्स को एक महत्वपूर्ण मात्रा में भौतिक और आभासी मेमोरी की आवश्यकता होगी।

एक प्रारंभिक बिंदु के रूप में स्टैक आकार को 512 केबी तक कम करने की कोशिश करें और देखें कि क्या यह आपके आवेदन के लिए अधिक थ्रेड बनाने में मदद करता है। मैं क्षैतिज स्केलिंग का पता लगाने की भी सलाह देता हूं, उदाहरण के लिए अधिक भौतिक या आभासी मशीनों में आपके आवेदन प्रसंस्करण को विभाजित करना।

64-बिट वीएम का उपयोग करते समय, वास्तविक सीमा OS भौतिक और आभासी मेमोरी उपलब्धता और ulimitc जैसे OS ट्यूनिंग मापदंडों पर निर्भर करेगी। मैं निम्नलिखित लेख को संदर्भ के रूप में भी सुझाता हूं:

OutOfMemoryError: नया देशी धागा बनाने में असमर्थ - समस्या डिमिस्टिफाई


5

अगर jvm को systemd के माध्यम से शुरू किया जाता है, तो कुछ लिनक्स OS में अधिकतम प्रक्रिया (कार्य वास्तव में थ्रेड्स) के अनुसार अधिकतम कार्य हो सकते हैं।

आप इसे "सेवा स्थिति" चलाकर देख सकते हैं और जांच सकते हैं कि क्या अधिकतम कार्य सीमा है। अगर वहाँ है, तो आप इसे हटा सकते हैं /etc/systemd/system.conf संपादन करके, एक विन्यास जोड़कर: DefaultTasksMax = infinity


3

मुझे भूत प्रक्रियाओं के कारण एक ही समस्या थी जो बैश में शीर्ष का उपयोग करते समय दिखाई नहीं देती थी। इसने जेवीएम को अधिक धागे को फैलने से रोका।

मेरे लिए, यह तब हल हुआ जब सभी java प्रोसेस को jps (सिर्फ jpsआपके शेल में निष्पादित ) के साथ सूचीबद्ध किया गया और उन्हें अलग-अलग का उपयोग करके मार दियाkill -9 pid प्रत्येक भूत प्रक्रिया के लिए bash कमांड मार दिया।

यह कुछ परिदृश्यों में मदद कर सकता है।


2

java.lang.OutOfMemoryError: Unable to create new native threadजब भी JVM OS से नया थ्रेड माँगता है, आपके सामने एक मौका होता है । जब भी अंतर्निहित OS एक नया देशी धागा आवंटित नहीं कर सकता है, इस OutOfMemoryError को फेंक दिया जाएगा। देशी थ्रेड्स की सटीक सीमा बहुत प्लेटफ़ॉर्म-निर्भर है, इस प्रकार नीचे दिए गए लिंक उदाहरण के समान परीक्षण चलाकर उन सीमाओं का पता लगाने की सलाह दी जाती है। लेकिन, सामान्य तौर पर, स्थिति java.lang.OutOfMemoryError: Unable to create new native threadनिम्न चरणों से गुजरती है:

  1. JVM के अंदर चलने वाले एप्लिकेशन द्वारा एक नया जावा धागा मांगा जाता है
  2. JVM नेटिव कोड OS के लिए एक नया देशी थ्रेड बनाने के लिए अनुरोध करता है। OS एक नया देशी थ्रेड बनाने की कोशिश करता है जिसे थ्रेड के लिए मेमोरी आवंटित करने की आवश्यकता होती है
  3. OS मूल मेमोरी आवंटन को अस्वीकार कर देगा क्योंकि 32-बिट जावा प्रोसेस साइज़ ने अपने मेमोरी एड्रेस स्पेस को कम कर दिया है - जैसे (2-4) GB प्रोसेस साइज़ की सीमा पर चोट लगी है - या OS की वर्चुअल मेमोरी पूरी तरह से ख़त्म हो गई है
  4. Java.lang.OutOfMemoryError: नई देशी थ्रेड त्रुटि बनाने में असमर्थ है।

संदर्भ: https://plumbr.eu/outofmemoryerror/unable-to-create-new-new-thread


2

यह जानने के लिए कि कौन सी प्रक्रियाएँ थ्रेड का निर्माण कर रही हैं:

ps huH

मैं आम तौर पर एक फ़ाइल के लिए आउटपुट को पुनर्निर्देशित करता हूं और फ़ाइल का ऑफ़लाइन विश्लेषण करता हूं (प्रत्येक प्रक्रिया के लिए थ्रेड काउंट अपेक्षित है या नहीं)


1

यदि आपकी नौकरी नोड्स पर आउटऑफमेमोरी के कारण विफल हो रही है, तो आप अपने अधिकतम नक्शे और रिड्यूसर की संख्या और प्रत्येक के लिए जेवीएम ऑप्स को ट्विट कर सकते हैं। mapred.child.java.opts (डिफ़ॉल्ट 200Xmx है) आमतौर पर आपके डेटा विशिष्ट हार्डवेयर के आधार पर बढ़ाना पड़ता है।

यह लिंक सहायक हो सकता है ... pls जाँच करें


1
हमने उस लिंक पर दिए गए परिवर्तन को पहले ही आज़मा लिया है। लेकिन परिणाम समान है :(
दीपक तेवानी

1

आपके JBoss कॉन्फ़िगरेशन में कुछ समस्याएँ हैं, /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms और Xmx आपके JBoss मेमोरी उपयोग को सीमित मान तक सीमित कर रहे हैं, इसलिए 8Gb से आपके पास सर्वर केवल 512M का उपयोग कर रहा है। + अपने स्वयं के उद्देश्य के लिए कुछ अतिरिक्त, उस संख्या को बढ़ाएं, ओएस और वहां चल रहे अन्य सामान के लिए कुछ मुफ्त छोड़ने के लिए याद रखें और हो सकता है कि आप इसे बिना कोड के चलाने के बावजूद चला रहे हों। यदि आप कर सकते हैं तो कोड को ठीक करना भी अच्छा होगा।


1

निम्नलिखित दो कारणों से यह त्रुटि हो सकती है:

  • नए थ्रेड्स को समायोजित करने के लिए मेमोरी में कोई जगह नहीं है।

  • थ्रेड्स की संख्या ऑपरेटिंग सिस्टम की सीमा से अधिक है।

मुझे संदेह है कि थ्रेड की संख्या जावा प्रक्रिया के लिए सीमा से अधिक है

तो संभवतः संभावना है कि मुद्दा यह है कि स्मृति के कारण एक बिंदु पर विचार करना है

धागे JVM के ढेर के भीतर नहीं बने हैं। वे JVM के ढेर के बाहर बनाए गए हैं। इसलिए अगर जेवीएम हीप आवंटन के बाद रैम में कम जगह बची है, तो एप्लिकेशन "java.lang.OutOfMemoryError: नए देशी धागे बनाने में असमर्थ" में चलेगा।

संभव समाधान ढेर स्मृति को कम करने या समग्र राम आकार को बढ़ाने के लिए है


0

मेरे पास यही मुद्दा था और यह एक जावा एपीआई का अनुचित उपयोग निकला। मैं एक बैच प्रोसेसिंग विधि में एक बिल्डर को इनिशियलाइज़ कर रहा था, जो कि एक से अधिक बार आरंभ नहीं होना चाहिए था।

मूल रूप से मैं कुछ ऐसा कर रहा था:

for (batch in batches) {
    process_batch(batch)
}

def process_batch(batch) {
    var client = TransportClient.builder().build()
    client.processList(batch)
}

जब मुझे यह करना चाहिए था:

for (batch in batches) {
    var client = TransportClient.builder().build()
    process_batch(batch, client)
}

def process_batch(batch, client) {
    client.processList(batch)
}

-4

सबसे पहले मैं उस OS / VM को दोष नहीं दूंगा .. बल्कि डेवलपर जिसने कोड लिखा है जो कई थ्रेड्स बनाता है । मूल रूप से आपके कोड (या 3rd पार्टी) में बहुत सारे थ्रेड बिना नियंत्रण के बनाए जाते हैं

स्टैकट्रैक्स / कोड की सावधानीपूर्वक समीक्षा करें और बनाए गए थ्रेड्स की संख्या को नियंत्रित करें। आम तौर पर आपके ऐप को थ्रेड्स की एक बड़ी मात्रा की आवश्यकता नहीं होनी चाहिए, अगर यह एक अलग समस्या है।


10
यह सवाल का हल नहीं है।
फुट्रिजिलो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.