2012-01-25 11 views
16

मेरे जावा प्रोग्रामबहुत अधिक फ़ाइलें खुली त्रुटि लेकिन lsof खुली फ़ाइलों के एक कानूनी संख्या

Caused by: java.io.IOException: Too many open files 
     at java.io.UnixFileSystem.createFileExclusively(Native Method) 
     at java.io.File.createNewFile(File.java:883)... 

यहाँ /etc/security/limits.conf से प्रमुख लाइनें हैं के साथ विफल हो रहा है पता चलता है। वे 500k पर एक उपयोगकर्ता के लिए अधिकतम फ़ाइलों सेट:

root      soft nofile   500000 
root      hard nofile   500000 
*      soft nofile   500000 
*      hard nofile   500000 

मैं फ़ाइलों की संख्या की गणना करने के लिए करने के लिए खोलने के lsof भाग गया - दोनों विश्व स्तर पर और JVM प्रक्रिया के द्वारा। मैंने /proc/sys/fs में काउंटर की जांच की। सब ठीक लगता है। मेरे प्रक्रिया केवल 4301 फ़ाइलों खुला है और सीमा 500k है:

:~# lsof | wc -l 
5526 
:~# lsof -uusername | wc -l 
4301 
:~# cat /proc/sys/fs/file-max 
744363 
:~# cat /proc/sys/fs/file-max 
744363 
:~# cat /proc/sys/fs/file-nr 
4736 0  744363 

यह एक उबंटू 11.04 सर्वर है। मैंने भी रिबूट किया है इसलिए मैं सकारात्मक हूं कि इन पैरामीटर का उपयोग किया जा रहा है।

मैं अगर यह प्रासंगिक है, लेकिन प्रक्रिया एक नवोदय स्क्रिप्ट, जो setuidgid का उपयोग कर प्रक्रिया शुरू होता है, इस तरह से शुरू कर दिया है पता नहीं है:

exec setuidgid username java $JAVA_OPTS -jar myprogram.jar 

मैं क्या याद आ रही है?

+0

अपनी ढेर जगह को अपडेट करने और इसे एक बड़ा अधिकतम देने का प्रयास करें। निश्चित नहीं है कि दोनों क्यों संबंधित होंगे, लेकिन मैंने अलग-अलग मुद्दों के असंख्य के लिए उस त्रुटि को मारा है। – Relic

+0

दिलचस्प, धन्यवाद। लेकिन यह पहले से ही -Xmx5800m है :) – hughw

+0

कुछ जहां प्रक्रिया पेड़ में आप ulimit का उपयोग कर नई सीमा निर्धारित कर रहे हैं? – Jayan

उत्तर

16

यह पता चला समस्या यह है कि मेरा कार्यक्रम एक नवोदय init स्क्रिप्ट के रूप में चल रहा था, और exec छंद नहीं है कि था एक खोल का आह्वान करें। ulimit और limit.conf में सेटिंग्स केवल शेल में उपयोगकर्ता प्रक्रियाओं पर लागू होती हैं।

मैं

exec sudo -u username java $JAVA_OPTS -jar program.jar 

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

I have seen it mentioned कि आप कमांड को आमंत्रित करने से पहले ulimit -n पर भी कॉल कर सकते हैं; अपस्टार्ट स्क्रिप्ट के लिए मुझे लगता है कि आप इसके बजाय script स्टांज़ा का उपयोग करेंगे।

खुले फ़ाइल डिस्क्रिप्टर की सटीक गणना प्राप्त करने के लिए lsofls /proc/{pid}/fd | wc -l होने के लिए मुझे बेहतर डायग्नोस्टिक मिला। निगरानी करके मैं देख सकता था कि असफलताएं 40 9 6 खुली एफडीएस पर हुईं। मुझे नहीं पता कि वह 40 9 6 कहां से आता है; यह कहीं भी/आदि में नहीं है; मुझे लगता है कि यह कर्नेल में संकलित है।

4

मैं एक सर्वर निर्माण स्क्रिप्ट के शीर्ष पर बैश के इस स्निपेट है:

# Jack up the max number of open file descriptors at the kernel 
echo "fs.file-max = 1000000" >> /etc/sysctl.conf 
invoke-rc.d procps start 

# Increase max open file descriptors for this process 
ulimit -n 1000000 

# And for future ones as well 
cat >> /etc/profile <<LIMITS 
ulimit -n 1000000 
LIMITS 
cat >> /etc/security/limits.conf <<LIMITS 
root - nofile 1000000 
LIMITS 
संबंधित मुद्दे