2010-02-16 17 views
57

मैं जावा में यह अपवाद हो रही है:बहुत अधिक फ़ाइलें खुली: कितने खुले हैं कि वे क्या कर रहे हैं, और कितने सकते हैं JVM खुला

java.io.FileNotFoundException: (Too many open files) 

मैं तरीके इस को खत्म करने के लिए देख रहा हूँ मुसीबत।

यह त्रुटि स्पष्ट रूप से इंगित करती है कि जेवीएम ने बहुत से हैंडल आवंटित किए हैं और अंतर्निहित ओएस इसे और अधिक नहीं होने देगा। या तो मुझे अनुचित बंद कनेक्शन/धाराओं के साथ कहीं रिसाव मिल गया है।

यह प्रक्रिया गैर-स्टॉप के दिनों तक चलती है और अंततः अपवाद फेंकता है। यह बार-बार 12-14 दिनों के बाद होता है।

आप इससे कैसे लड़ते हैं? क्या JVM में आवंटित हैंडल की सूची प्राप्त करने का कोई तरीका है या जब यह निश्चित राशि को ट्रैक करता है तो ट्रैक करें? मुझे उन्हें मुद्रित करना अच्छा लगेगा और देखें कि यह कैसे बढ़ता है और कब। मैं एक प्रोफाइलर का उपयोग नहीं कर सकता क्योंकि यह एक उत्पादन प्रणाली है और इसे विकास में पुन: उत्पन्न करने में कठिनाइयां हैं। कोई उपाय?

मैं मुक्त ढेर आकार की निगरानी कर रहा हूं और "अलार्म" उठा रहा हूं जब यह कुल निर्दिष्ट एक्सएक्स में 1% तक पहुंचता है। मुझे यह भी पता है कि अगर मेरी थ्रेड गिनती 500 से ऊपर हिट हो जाती है, तो कुछ निश्चित रूप से हाथ से बाहर हो जाता है। अब, यह जानने का कोई तरीका है कि मेरा जेवीएम आवंटित ओएस से बहुत से हैंडल करता है और उन्हें वापस नहीं देता है, उदा। सॉकेट, खुली फाइलें, आदि। अगर मुझे पता चलेगा, तो मुझे पता चलेगा कि कहां देखना है और कब।

+1

आप और अधिक प्रदान कर सकते हैं जेवीएम और ओएस के बारे में जानकारी? इसके अलावा, मेरा सुझाव है कि आप विकास वातावरण में इसे पुन: पेश करने में अधिक प्रयास करें। यह एक परेशानी हो सकती है, लेकिन जब आपको ऐसी समस्या हो, तो उत्पादन प्रणाली पर "निरीक्षण और रिपोर्ट" करने का प्रयास करने में अधिक समय लगेगा। – Timothy

+1

यह लिनक्स पर बार-बार होता है जो वर्चुअलाइज्ड चलाता है और हमारे पास वास्तव में 2 सप्ताह भारी भारित परीक्षण चलाकर इसे पुन: पेश करने का विकल्प नहीं होता है। मैंने इसे विंडोज़ बक्से पर नहीं देखा है। आप सही हैं, इसे देव में पकड़ना सबसे अच्छा है, लेकिन मैं भी भविष्य में स्वयं निगरानी के लिए सर्वर में एम्बेडेड कुछ क्षमता रखना चाहता हूं। – Dima

+1

अपने संपादन आरई। मुझे नहीं लगता कि जेवीएम आपको यह बताने में सक्षम है कि उसने कितनी फाइलें खोली हैं। सूर्य को जोड़ने के लिए यह एक अच्छी सुविधा हो सकती है, लेकिन तब तक आपको बताने के लिए बाहरी प्रक्रिया का उपयोग करना होगा। यदि आपको वास्तव में JVM के अंदर इसकी आवश्यकता है तो कुछ कोड लिखें जो lsof निष्पादित करता है और परिणाम देता है। अतिरिक्त रूप से खुली फ़ाइलों की सीमा को बदला जा सकता है। उदाहरण के लिए लिनक्स में आप /etc/security/limits.conf फ़ाइल को संशोधित कर सकते हैं। – bramp

उत्तर

27

आप नहीं कहा जो ओएस आप पर चल रहे हैं, लेकिन अगर आप लिनक्स पर चल रहे हैं आप lsof आदेश

lsof -p <pid of jvm> 

बस इतना ही JVM द्वारा खोली गई फ़ाइलों सूची जाएगा उपयोग कर सकते हैं। या यदि आप विंडोज़ पर चल रहे हैं तो आप Process Explorer कर सकते हैं जो सभी प्रक्रियाओं के लिए सभी खुली फाइलें दिखाएगा।

ऐसा करने से उम्मीद है कि आप कोड को खोलने के लिए कोड का कौन सा हिस्सा कम कर सकते हैं।

+0

अच्छा विचार। प्रत्येक एक्स सेकंड को दोहराने के लिए आप 'lsof' पर जा सकने वाले झंडे की जांच करें। – Timothy

+0

मैंने लिनिक्स के बारे में टिप्पणी जोड़ा है।, Lsof tip के लिए धन्यवाद! – Dima

+2

मुझे यह जानने में दिलचस्पी होगी कि क्या मेरे समाधान ने आपको समस्या को ट्रैक करने में मदद की है। अगर यह गोपनीय या बहुत परेशानी नहीं है तो क्या आप समझा सकते हैं कि अंत में समस्या का कारण क्या था? – bramp

23

चूंकि आप लिनक्स पर हैं, तो मैं सुझाव दूंगा कि आप/proc-filesystem की जांच करें। Proc के अंदर, आपको एक फ़ोल्डर को आपके प्रक्रिया के पीआईडी ​​के साथ एक फ़ोल्डर कैल्ड 'एफडी' युक्त मिलेगा। यदि आपका प्रक्रिया आईडी 1234, पथ (कर एक 'ls -l')

/proc/1234/fd 

उस फ़ोल्डर के अंदर हो, आप सभी खोला फ़ाइलों के लिंक मिल जाएगा है। आमतौर पर, आप फ़ाइल नाम से बता सकते हैं कि लाइब्रेरी/कोड फ़ाइल खोल सकता है और फ़ाइल बंद नहीं कर सकता है।

+0

धन्यवाद, यह उपयोगी है लेकिन मैं जो कुछ भी कर रहा हूं वह कुछ है जो फ़ाइल सिस्टम या ओएस में खोदने से बच जाएगा। मैं चाहता हूं कि जेवीएम प्रक्रिया मुझे बताए कि यह "बीमार" क्यों है, कारण मैं चाहता हूं कि उपयोगकर्ताओं को सिरदर्द छोड़ना कुछ गलत हो। – Dima

10

आप जोड़कर खोली गई फ़ाइलों की सीमा को बदल सकते हैं /etc/security/limits.conf के लिए निम्न:

* soft nofile 2048 # Set the limit according to your needs 
* hard nofile 2048 

तो फिर तुम विन्यास खोल पर sysctl -p का उपयोग कर फिर से लोड कर सकते हैं। this article देखें।

बस संपूर्णता के लिए आप सत्यापित कर सकते क्या का उपयोग कर खोला फ़ाइलों के लिए वर्तमान सीमा है: ulimit -n

10

तो, पूरा जवाब (मैं @phisch और @bramp से जवाब संयुक्त)। यदि आप सभी प्रक्रियाओं को देखना चाहते हैं, तो आपको sudo का उपयोग करना चाहिए। परिणाम को फ़ाइल में सहेजना भी अच्छा है - lsof सस्ता नहीं है + यह फ़ाइल आगे की जांच के लिए उपयोगी हो सकती है।

sudo lsof > lsof.log 

दिखाएँ बुरे लोगों के रूप में अच्छी तरह से फाइल करने के लिए

cat lsof.log | awk '{ print $2 " " $1; }' | sort -rn | uniq -c | sort -rn | head -5 

    2687 114970 java 
    131 127992 nginx 
    109 128005 nginx 
    105 127994 nginx 
    103 128019 nginx 

फ़ाइल डिस्क्रिप्टर की सूची सहेजें:

sudo ls -l /proc/114970/fd > fd.log 

शीर्ष दिखाएँ खुली फ़ाइलों:

cat fd | awk '{ print $11 }' | sort -rn | uniq -c | sort -rn | head -n20 
+2

बहुत बहुत धन्यवाद, वास्तव में उपयोगी! मुझे लगता है कि आप तीसरे कमांड में एक टुकड़ा भूल गए हैं, हालांकि: यह 'sudo ls -l/proc/114970/fd> fd.log' – ocramot

+0

@ocramot होना चाहिए, आपका स्वागत है! अनुलेख तुम सही थे, मैंने अपना जवाब तय कर दिया। – Jimilian

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