2010-08-17 18 views
6

मैं इसjava.lang.OutOfMemoryError: नई देशी धागा बनाने में असमर्थ

one place i have seen this problem is if you keep creating threads, and instead of calling start(), call run() directly on the thread object. This will result in the thread object not getting dereferenced... So after sometime the message unable to create new native thread comes up

Sun Java Forums

अपने आवेदन में पर

की तरह टिप्पणी को देखा, initialy हम धागा उपयोग करने की योजना है, लेकिन बाद, हमने तय किया अब और आवश्यकता नहीं है, इसलिए हम केवल शुरू() के बजाए रन() को कॉल करते हैं। क्या हमें नए थ्रेड क्लास (..) के लिए मैन्युअल जीसी करने की ज़रूरत है?

मेरी बिल्ला स्टार्टअप की स्थापना

-Xms1024m -Xmx1024m -XX:MaxPermSize=450m 
+3

लेकिन, यदि आप शुरू करने के बजाए रन() को उत्साहित करते हैं() JVM एक नया थ्रेड नहीं बनाएगा। यही है ना – sourcerebels

+0

सहमत हुए। तो भले ही मैं अपनी सेवा परत विधि पर नया थ्रेड क्लास (..) का उपयोग करता हूं, मैन्युअल साफ करने की आवश्यकता नहीं है? – cometta

+0

आपको टोमकैट (एक वेब सर्वर) के अंदर थ्रेड बनाने की आवश्यकता क्यों है? यह अनुशंसित नहीं है। वैकल्पिक समाधान खोजने का प्रयास करें: 1) आरएमआई, जेएमएस या डेटाबेस के माध्यम से संचारित धागे के साथ एक अलग स्टैंडअलोन प्रक्रिया; 2) शायद आपके वेब एप्लिकेशन के अंदर MessageDrivenBeans और JMS का उपयोग करके, यदि आप JBEE, Glassfish या Geronimo जैसे J2EE ऐप सर्वर में बदलने के साथ ठीक हैं; 3) अन्य ... :) – helios

उत्तर

11

आप पहली जगह Thread क्यों बनाते हैं?

आपके कोड को इसके बजाय Runnable इंटरफ़ेस लागू करना चाहिए।

तब, जब आप तय करते हैं कि आप एक सूत्र में उसे चलाना चाहते हैं, सरल इन्स्तांत तर्क के रूप में Runnable के साथ एक Thread और Thread वस्तु पर start() कहते हैं।

यदि, इसके बजाय, आप इसे अपने वर्तमान थ्रेड में चलाने के लिए चाहते हैं, तो बस अपने Runnable ऑब्जेक्ट पर run() पर कॉल करें।

  • आप जब तक आप अलग धागे के बारे में परवाह नहीं है के रूप में किसी भी Thread वस्तुओं शामिल नहीं है
  • अपने कोड एक Runnable जो करीब धारणात्मक फिट बैठता में लपेटा जाता है:

    यह कई फायदे हैं आप कुछ विशेष प्रकार के धागे नहीं लिख रहे हैं, क्या आप? आप बस कुछ कोड लिखते हैं जिन्हें निष्पादित/चलाया जा सकता है।

  • आप आसानी से एक Executor जो आगे सार दूर निर्णय

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

+0

आपका मतलब है कि मेरा थ्रेड क्लास इस समस्या का कारण थ्रेड फैलाता है?भले ही मैं बस शुरू करने के बजाए रन() को कॉल करता हूं? – cometta

+2

@ कॉर्नेटा - वह यह नहीं कह रहा है कि इससे समस्याएं आती हैं। वह कह रहा है कि 'थ्रेड 'बढ़ाने के लिए यह * खराब अभ्यास * है। –

+0

इसके अलावा, एक ही नस में, एक निष्पादक का उपयोग क्यों नहीं करें? –

4

जब आप() विधि कोई नया धागा बनाया जाना चाहिए चलाने के कॉल। और जब आपकी सामग्री का संदर्भ नहीं दिया जाता है तो आपकी वस्तुएं कचरा कलेक्टर द्वारा एकत्र की जाएंगी।

कोड का आपका अन्य भाग बहुत सारे थ्रेड बना सकता है।

अपने आवेदन में धागे को सीमित करने के लिए अपने कोड में ThreadPoolExecutor (थ्रेड पूलिंग) का उपयोग करने का प्रयास करें, और बेहतर प्रदर्शन के लिए अपने थ्रेडपूल आकार को ट्यून करें।

आप भी अपने मुद्दे को डीबग करने के लिए निम्न देख सकते हैं: (लिंक से संदर्भित) वहाँ अगर आप इस अपवाद का सामना करने के लिए कुछ चीजें हैं।

  • कितने धागे इस प्रक्रिया के लिए सक्रिय हैं देखने के लिए lsof -p पीआईडी ​​आदेश (यूनिक्स प्लेटफार्मों) का प्रयोग करें।
  • निर्धारित करें कि अधिकतम ऑपरेटिंग सिस्टम द्वारा परिभाषित प्रति प्रक्रिया धागे की संख्या है या नहीं। यदि आवेदन एप्लिकेशन के लिए बहुत कम है, तो प्रति-प्रक्रिया थ्रेड सीमा को बढ़ाने का प्रयास करें।
  • की जांच के लिए आवेदन कोड निर्धारित यदि कोड है कि धागे या कनेक्शन (LDAP कनेक्शन के रूप में ऐसी ) और नहीं बनाने के लिए उन्हें नष्ट करने है। जावा थ्रेड को यह देखने के लिए कि अत्यधिक संख्या बनाई गई है, तो आप डंप कर सकते हैं।
  • यदि आपको लगता है कि बहुत से कनेक्शन एप्लिकेशन द्वारा खोले गए हैं, तो सुनिश्चित करें कि एप्लिकेशन बनाता है कोई भी थ्रेड नष्ट हो गया है। एक एंटरप्राइज़ एप्लिकेशन (.ear) या वेब एप्लिकेशन (.war) लंबे समय से चलने वाले JVM के अंतर्गत चलता है। सिर्फ इसलिए कि एप्लिकेशन समाप्त हो गया है इसका मतलब यह नहीं है कि है कि JVM प्रक्रिया समाप्त होती है। यह आवश्यक है कि एक आवेदन मुक्त जो भी संसाधन आवंटित करता है। के लिए एक और समाधान पर थ्रेड पूल का उपयोग करने के लिए आवश्यक थ्रेड प्रबंधित करने के लिए होगा।
1

यह लिंक काफी अच्छी तरह से कैसे इस त्रुटि JVM द्वारा फेंक दिया जाता है वर्णन करता है: http://javaeesupportpatterns.blogspot.ro/2012/09/outofmemoryerror-unable-to-create-new.html

मूल रूप से यह ओएस पर बहुत निर्भर है। रेडहाट लिनक्स 6.5 (अधिकतर अन्य डिस्ट्रोज़/संस्करण और कर्नेल संस्करण) पर max_threads = max_process x 2.

थ्रेड की अधिकतम संख्या अनुमत प्रक्रियाओं की संख्या पर बहुत निर्भर है। जो प्रक्रियाओं की अधिकतम संख्या आपके द्वारा स्थापित अधिकतम भौतिक स्मृति पर निर्भर है।

यदि आपके पास limit.conf फ़ाइल में है (मेरे आरएचएल 6.5 पर यह /etc/security/limits.d/90-nproc.conf में है)। फ़ाइल भरें:

# Default limit for number of user's processes to prevent 
# accidental fork bombs. 
# See rhbz #432903 for reasoning. 

*   soft nproc  **1024** 
root  soft nproc  unlimited 

आप देखेंगे कि गैर रूट उपयोगकर्ताओं के लिए यह 1024 है (जिसका अर्थ है 2048 अधिकतम धागे)।

आपके उपयोगकर्ता को चलाने के लिए अनुमति देने वाले थ्रेड की अधिकतम संख्या को देखने के लिए यह आदेश "cat/proc/sys/kernel/threads-max" या "sysctl kernel.threads-max" चलाता है।

इस तरह एक मुद्दा हल करने के लिए (कम से कम यह मेरे लिए काम किया) रूट के रूप में आप अधिकतम अनुमति धागे ncrease करना होगा:

गूंज 10000>/proc/sys/कर्नेल/धागे-अधिकतम

यह सभी उपयोगकर्ताओं और रूट को प्रभावित करता है। उपयोगकर्ता को लॉग आउट करने की आवश्यकता होती है और फिर सेटिंग्स को प्रभावी होने के लिए फिर से लॉग इन करने की आवश्यकता होती है।

संबंधित मुद्दे