2013-04-11 8 views
10

आवेदन मैं अचानक पर काम कर रहा हूँ"बहुत अधिक फ़ाइलें खुली" डिबगिंग मुद्दा

java.io.IOException: ... Too many open files 

मैं मुद्दा यह मतलब है कि फ़ाइलों को खोला जाता है, लेकिन बंद नहीं समझते हैं के रूप में के साथ दुर्घटनाग्रस्त हो गया।

निश्चित रूप से स्टैकट्रेस इस तथ्य के बाद होता है और केवल मदद कर सकते हैं क्या घटना त्रुटि हुई पहले समझते हैं।

इस मुद्दे केवल तब होता है जब एप्लिकेशन उच्च तनाव लोड किया जा रहा है लगता है जो खोजने के लिए अपने कोड बेस खोज करने के लिए एक बुद्धिमान तरीका होगा क्या।

+0

आप बहु सूत्रण फ़ाइल संभाल रहे हैं, या यह सभी एक ही धागे पर किया जाता है? और क्या आपने वर्कलोड प्रबंधित करने के लिए * कंसुरेंसी थ्रॉटलिंग * माना है? – christopher

उत्तर

9

मैं सबसे अच्छा तरीका है विशेष रूप से इस प्रयोजन के लिए डिजाइन उपकरण का उपयोग करने के बारे में सोच है, इस तरह के रूप में this one:

इस छोटे जावा एजेंट एक टूल है जो जहां// जो अपने JVM में फ़ाइलों को खोला का ट्रैक रखता है । आप एक्सेस ऑपरेशन के बारे में पता लगाने या लीक को संभालने के लिए एजेंट को इन परिचालनों का पता लगा सकते हैं, और वर्तमान में खुली फ़ाइलों की सूची को डंप कर सकते हैं और कहां/कब/किसने खोला है।

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

मुझे लगता है कि YourKit को इसके आसपास कुछ सुविधाएं भी हैं, लेकिन इस समय कोई विशिष्ट जानकारी नहीं मिल सकती है।

3

क्या ओएस? यदि यह लिनक्स/मैक है, तो information under /proc है जो मदद करनी चाहिए। विंडोज़ पर, Process Explorer का उपयोग करें।

जहां तक ​​कोड बेस खोज रहे हैं, शायद IOException को पकड़ने या बढ़ाने वाले कोड की तलाश करें - मुझे लगता है कि I/O विधियों को पहले से पकड़ने/बढ़ाने के लिए close() कॉल की आवश्यकता होने की उच्च संभावना है।

9
  1. फ़ाइल संदर्भों के कारण को देखने के लिए lsof -p pid का उपयोग करें;

  2. एक प्रक्रिया के खुले फ़ाइल संदर्भों की सीमा को देखने के लिए ulimit -n का उपयोग करें;

  3. जांच अपनी परियोजना में किसी भी IO संसाधन, वे समय में जारी कर रहे हैं?, कि, File, Process, Socket (और HTTP कनेक्शन) नोट सभी आईओ संसाधन हैं।

  4. कभी कभी, बहुत सारे सूत्र भी इस समस्या का कारण होगा।

+0

'के बारे में बहुत बढ़िया बिंदु के अनुसार – JAM

+0

lsof'' lsof -p pid' मैं 3000 फ़ाइलों पल में खोला है, जबकि 'ulimit -n' फ़ाइल संदर्भ – cahen

+0

+1 इस मदद की तुलना में 2560 शायद पहली आदेश गिनती कुछ अलग है मुझे एक प्रक्रिया के खराब उपयोग के साथ एक एंड्रॉइड ऐप डीबग करने के लिए। सिस्टम की पिंग के साथ Runtime.exec()। मुझे waitFor() को ठीक करने के लिए process.destroy() को कॉल करना पड़ा था। – Rombus

3

क्या आपने jvisualvm (जावा 5.0 और बाद में जेडीके बिन निर्देशिका में) का उपयोग कर चल रही प्रक्रिया को जोड़ने का प्रयास किया है। आप चल रही प्रक्रिया को खोल सकते हैं और एक हीप डंप कर सकते हैं (यदि आपके पास पुराना जेडीके है तो आपको ग्रहण या इंटेलिज या नेटबीन्स एट अल का उपयोग करके विश्लेषण करने की आवश्यकता होगी।)।

JDK 7 हीप डंप बटन "मॉनिटर" टैब के अंतर्गत है। यह एक हीप डंप टैब, "क्लासेस" सब-टैब बनाएगा, जिसे आप जांच सकते हैं और देख सकते हैं कि फाइलों को खोलने वाली कोई भी कक्षा उच्च मात्रा में मौजूद है या नहीं। एक और बहुत ही उपयोगी विशेषता हेप डंप की तुलना है, इसलिए आप एक संदर्भ ढेर डंप ले सकते हैं, अपने ऐप को थोड़ी देर तक चलाएं और फिर एक और ढेर डंप लें और तुलना करें (तुलना करने के लिए लिंक "[हेपडम्प]" टैब पर है जब आप एक लेते हैं।क्रैश या ओओएम अपवाद पर हेपडम्प लेने के लिए जावा में एक झंडा भी है, यदि आप ढेर डंप की तुलना करते हैं तो आप उस मार्ग से नीचे जा सकते हैं जो आपको एक स्पष्ट वर्ग नहीं देता है जो समस्या पैदा कर रहा है। इसके अलावा, हीप डंप डिफ में "इंस्टेंस" उपटैब आपको दिखाएगा कि उस समय में दो ढेर डंप के बीच आवंटित किया गया है जो मदद भी कर सकता है।

jvisualvm एक भयानक उपकरण है जो पर्याप्त नहीं मिलता है उल्लेख है।

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