2012-05-24 13 views
11

मैं इस त्रुटि के कारण एक दिन से अधिक समय तक दीवार पर अपने सिर को पढ़ रहा हूं और परीक्षण कर रहा हूं।जावा 'आउटऑफमेमरी एरर' बनाते समय <100 धागे

मैं एक वर्ग Listener कहा जाता है कि इस

ExecutorService executor = Executors.newFixedThreadPool(NTHREADS); 
boolean listening = true; 
int count = 0; 
while (listening) { 
    Runnable worker; 
    try { 
     worker = new ServerThread(serverSocket.accept()); // this is line 254 
     executor.execute(worker); 
     count++; 
     logger.info("{} threads started", count); 
    } catch (Exception e1){ 
     //... 
    } 
} 

जैसे मैं JVM फेरबदल किया गया है (104k से 512 एम के लिए कहीं भी) (कहीं भी 15 जी 1 से) -Xmx सेटिंग्स और -Xss लग रहा है में कुछ जावा कोड है। सर्वर में 24 जीबी रैम है, लेकिन प्रोग्राम का समर्थन करने वाले डेटाबेस को भी चलाया जाना चाहिए।

java version "1.6.0_24" 
OpenJDK Runtime Environment (IcedTea6 1.11.1) (fedora-65.1.11.1.fc16-x86_64) 
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode) 

वहाँ हमेशा एक बड़ी है:

के बाद 2-20 धागे बनाए जाते हैं (कुछ दर्जन कार्यक्रम में कहीं मौजूद रूप में अच्छी तरह), मैं त्रुटि

Exception in thread "Thread-0" java.lang.OutOfMemoryError: unable to create new native thread 
at java.lang.Thread.start0(Native Method) 
at java.lang.Thread.start(Thread.java:657) 
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:943) 
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1325) 
at xxx.Listener.run(Listener.java:254) 

$java -version पैदावार प्राप्त जब ऐसा होता है तो सिस्टम पर मुफ्त मेमोरी की मात्रा, और अन्य प्रोग्राम ठीक से निष्पादित करना जारी रखते हैं। जावा को यह सोचने का क्या कारण है कि इसमें नए धागे के लिए कोई और स्मृति नहीं है?

अद्यतन: शायद यह बड़ा है की तुलना में मैं सोचा, मैं यह त्रुटि (केवल एक बार) जब मैं ^C इस्तेमाल किया पाने में कामयाब रहे:

OpenJDK 64-Bit Server VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated 

और एक ही हुआ जब मैं मारने की कोशिश की क्लाइंट (जावा में भी लिखा गया है और उसी सर्वर पर चल रहा है, यह एक सिंगल थ्रेड है जो एक फाइल पढ़ता है और इसे सॉकेट पर सर्वर पर भेजता है), इसलिए निश्चित रूप से जेवीएम से परे एक सीमा है जिससे कोई दूसरे के साथ हस्तक्षेप कर सकता है, लेकिन मैं कल्पना नहीं कर सकता कि अगर मुझे अभी भी मुफ्त मेमोरी है और मैं स्वैप का उपयोग नहीं कर रहा हूं? सर्वर -Xmx1G -Xss104k ग्राहक -Xmx10M

UPDATE2: पर्ल Forks::Super पुस्तकालय छोड़ना और पार्टी से ग्राहकों को चलाने से पहले सर्वर OOME साथ दुर्घटनाग्रस्त हो गया मुझे 34 धागे अप करने के लिए मिलता है, तो कई ग्राहकों चल निश्चित रूप से एक प्रभाव पड़ा सर्वर पर, लेकिन साथ ही मुझे एक समय में 34 से अधिक (68 यदि कोई क्लाइंट की गणना करता है) जावा थ्रेड चलाने में सक्षम होना चाहिए। कौन से सिस्टम संसाधन अधिक धागे के निर्माण को अवरुद्ध कर रहे हैं (यानी मुझे हॉग ढूंढना चाहिए)? जब सब कुछ (ग्राहकों, सर्वर, जीसी ...) चलाता है एक ही समय में स्मृति से बाहर, top मेरी सीपीयू और स्मृति के उपयोग के बारे में इस का कहना है:

Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st 
Mem: 24681040k total, 1029420k used, 23651620k free, 30648k buffers 
Swap: 26836988k total,  0k used, 26836988k free, 453620k cached 

Update3: hs_error लॉग करता है नीचे है कि संकेत मिलता है मेरी जावा 64 बिट नहीं है?

# There is insufficient memory for the Java Runtime Environment to continue. 
# Cannot create GC thread. Out of system resources. 
# Possible reasons: 
# The system is out of physical RAM or swap space 
# In 32 bit mode, the process size limit was hit 
# Possible solutions: 
# Reduce memory load on the system 
# Increase physical memory or swap space 
# Check if swap backing store is full 
# Use 64 bit Java on a 64 bit OS 
# Decrease Java heap size (-Xmx/-Xms) 
# Decrease number of Java threads 
# Decrease Java thread stack sizes (-Xss) 
# Set larger code cache with -XX:ReservedCodeCacheSize= 
# This output file may be truncated or incomplete. 
# 
# JRE version: 6.0_24-b24 
# Java VM: OpenJDK 64-Bit Server VM (20.0-b12 mixed mode linux-amd64 compressed oops) 
# Derivative: IcedTea6 1.11.1 
# Distribution: Fedora release 16 (Verne), package fedora-65.1.11.1.fc16-x86_64 
+0

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

+0

सर्वर थ्रेड मेरे स्वयं के बनाने के लिए एक खराब नामित वर्ग है 'पब्लिक क्लास सर्वर थ्रेड इम्प्लेमेंट्स रननेबल {... सार्वजनिक शून्य रन() {...} ...} ' मुझे आपकी चिंता दिखाई देती है कि यह प्रतीक्षा करना बुरा हो सकता है एक पूल में इनपुट (एक टाइमआउट फ़ंक्शन होता है), लेकिन जब भी कोई ग्राहक कनेक्ट होता है तो मैं एक नया धागा नहीं बनाना चाहता- यह अपेक्षाकृत कम अंतःक्रियाओं के लिए भारी ओवरहेड होगा और फिर भी मेरी थ्रेड निर्माण समस्याओं को हल नहीं करेगा। – kaz

+0

क्या आपने यह देखने के लिए परीक्षण किया है कि आप एक सरल एप्लिकेशन में कितने थ्रेड बना सकते हैं? – Jivings

उत्तर

11

आप max user processes द्वारा सीमा हो सकती है, अपनी सीमा उपयोग पता करने के लिए:

ulimit -u 

सीमा बदलने के लिए:

/etc/security/limits.conf सेट में:

user soft nproc [your_val] 
user hard nproc [your_val] 

आप कुछ जोड़ना पड़े अन्य कॉन्फ़िगरेशन अगर यह पर्याप्त नहीं है तो यह link देखें।

नोट: ओपी को फेडोरा और सेंटोस में यह bug report मिला जो /etc/security/limits.conf संपादित करने की सीमाओं को बताता है।

+0

मुझे डर दिया जाएगा यदि वह * मेरे सिरदर्द का कारण Centos 6 के संस्करण के साथ है जिसका उपयोग मैं कर रहा हूं। वाइल्डकार्ड (*) जंगली में दंडित। सिर्फ मुझे नहीं बल्कि समर्थक समर्थन लोगों को इसके बारे में पता नहीं था – nir

3

आपकी समस्या संभवतः जेवीएम से संबंधित है जो नए धागे के लिए स्टैक मेमोरी आवंटित करने में असमर्थ है। विडंबना यह है कि, इस समस्या को हीप स्पेस (-एक्सएमएक्स) और स्टैक स्पेस (-एक्सएसएस) को कम करके हल किया जा सकता है। उदाहरण के लिए, उदाहरण के लिए, एक अच्छी व्याख्या के लिए यहां देखें: http://www.blogsoncloud.com/jsp/techSols/java-lang-OutOfMemoryError-unable-to-create-new-native-thread.jsp

+0

मेरी इच्छा है कि यह इतना आसान था, लेकिन किसी भी तरह '-Xmx1G -Xss104k' के साथ मैं 6 धागे बनाने में सक्षम था (कुल मिलाकर 40 से कम मेरे कार्यक्रम में बनाया गया)।104k मेरे सिस्टम पर न्यूनतम -Xss मान है, और 1 जी कहीं भी उतना ही बड़ा नहीं है जितना इसे उत्पादन में होना चाहिए। इस बीच सिस्टम पर अभी भी एक बड़ी राशि (8 जी से अधिक) मुक्त है जब यह स्मृति से बाहर हो जाती है। – kaz

+0

104k एक अजीब मूल्य है :) यह दस्तावेज़ लगभग 64k न्यूनतम http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#threads_oom –

+0

वास्तव में अजीब है, लेकिन जब मैं 104 से कम के साथ JVM प्रारंभ करता हूं इस संदेश और क्रैश को फेंकता है: 'निर्दिष्ट स्टैक आकार बहुत छोटा है, कम से कम 104k निर्दिष्ट करें जावा वर्चुअल मशीन नहीं बना सका। – kaz

3

इसमें आपके नए धागे के लिए स्मृति नहीं है, इसमें वास्तविक धागे गुम हैं। सिस्टम शायद आपको रोक रहा है: उपयोगकर्ता द्वारा बनाए जा सकने वाले थ्रेड की संख्या की सीमा है।आप इसे इस तरह से क्वेरी कर सकते हैं:

cat /proc/sys/kernel/threads-max 

ध्यान दें कि आप एक ही मशीन पर अन्य प्रक्रियाओं से प्रभावित किया जा सकता है, तो आप वे भी कई धागा पैदा करते हैं। आप इस प्रश्न का उपयोगी लग सकते: Maximum number of threads per process in Linux?

+0

'$ cat/proc/sys/kernel/threads-max' एक सर्वर पर 385345- मेरा प्रोग्राम चला रहा है, कुछ एसएसएच/बैश शैल, और MySQL, मुझे नहीं लगता कि मैं उस सीमा को मार रहा हूं। इसके अलावा, कुछ विशेष रूप से भयानक जेवीएम सेटिंग्स दूसरों के मुकाबले कम धागे बनने के बाद मरने का कारण बनती हैं, जो बताती है कि यह एक जेवीएम मुद्दा है। – kaz

1
बस स्पष्टीकरण के लिए

:

आप Thread करने के लिए एक ServerSocket प्रदान करते हैं। क्या आप उस सॉकेट को डेटा भेजते हैं? हो सकता है कि आप थ्रेड-कॉन्टेक्स्ट के भीतर अधिक डेटा स्टोर करें। एक पैटर्न के लिए एक नज़र डालें, जहां आप byte[] में स्ट्रीमडाटा स्टोर करते हैं।

+0

नहीं, मैं धागे को 'सॉकेट' प्रदान करता हूं, 'ServerSocket.accept()' 'सॉकेट 'ऑब्जेक्ट देता है। और हाँ, मैं इसे किसी अन्य प्रोग्राम से डेटा पास करता हूं और उस डेटा को पढ़ता हूं, इसे संसाधित करता हूं, और फिर डिस्कनेक्ट करता हूं। परीक्षण संस्करण में, थ्रेड बस सॉकेट स्वीकार करता है, इंतजार करता है, फिर उसे बंद कर देता है और मर जाता है। सॉकेट को स्ट्रीम की तरह पढ़ा जाता है, इसलिए मुझे नहीं लगता कि मैं उस स्ट्रीम की पूरी सामग्री को धागे में भेज रहा हूं। इसके अलावा, क्लाइंट प्रमाणीकृत होने तक, यह डेटा नहीं भेजता है, स्ट्रीम बफर में केवल कुछ सौ बाइट होंगे। – kaz

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

  • कोई संबंधित समस्या नहीं^_^