2013-02-26 111 views
9

मेरे पास उत्पादन पर चलने वाली नौकरी है जो xml फ़ाइलों को संसाधित करती है। एक्सएमएल फाइलें लगभग 4k और आकार 8 से 9 जीबी की गणना करती हैं।एरर्नो :: ENOMEM: स्मृति आवंटित नहीं किया जा सकता - बिल्ली

प्रसंस्करण के बाद हमें आउटपुट के रूप में सीएसवी फाइलें मिलती हैं।

errno :: ENOMEM: मैं एक बिल्ली आदेश जो एक एकल फाइल मैं हो रही है करने के लिए सभी CSV फ़ाइलों में मर्ज हो जाएगी है पर cat (backtick) आदेश स्मृति को आबंटित नहीं किया जा सकता

नीचे कुछ विवरण हैं:

  • सिस्टम मेमोरी - 4 जीबी
  • स्वैप - 2 जीबी
  • रूबी: 1.9.3p286

फ़ाइलें nokogiri और saxbuilder-0.0.8 का उपयोग कर कार्रवाई की जाती है।

यहाँ, कोड जो 4000 एक्सएमएल फाइल को संसाधित करने और उत्पादन होगा के एक ब्लॉक सीएसवी में सहेजा जाता है (1 एक्सएमएल प्रति) (माफ करना, मैं कंपनी की नीति के b'coz साझा करने के लिए लगता है कि नहीं कर रहा हूँ) है।

नीचे कोड है जो एक एकल फाइल

Dir["#{processing_directory}/*.csv"].sort_by {|file| [file.count("/"), file]}.each {|file| 
      `cat #{file} >> #{final_output_file}` 
} 

मैं स्मृति की खपत स्नैपशॉट लिया है के दौरान processing.It स्मृति के लगभग सभी हिस्से की खपत करने के लिए उत्पादन फ़ाइलों में मर्ज हो जाएगी है, लेकिन, ऐसा नहीं होगा असफल। यह हमेशा cat कमांड पर विफल रहता है।

मुझे लगता है कि बैकटिक पर यह एक नई प्रक्रिया को फोर्क करने की कोशिश करता है जिसे पर्याप्त स्मृति नहीं मिलती है, इसलिए यह विफल हो जाती है।

कृपया मुझे अपनी राय और इसके बारे में बताएं।

+0

आईएमओ वास्तव में यह दिखाने के लिए समझ में आता है कि आप क्या कर रहे हैं। –

+0

@ डेव न्यूटन मैंने अपनी पोस्ट संपादित की है, आपके उत्तर के लिए धन्यवाद – Atith

+0

आप ऐसा होने के लिए स्मृति पर बहुत कम हो सकते हैं, क्या आप सुनिश्चित हैं कि आपके पास पर्याप्त स्मृति शेष है? 'Free -m'' का आउटपुट क्या है? – Intrepidd

उत्तर

2

तो ऐसा लगता है कि आपका सिस्टम स्मृति पर बहुत कम चल रहा है और एक शेल + कॉलिंग बिल्ली को उजागर करने के लिए कुछ स्मृति शेष है।

यदि आपको कुछ गति खोने पर कोई फर्क नहीं पड़ता है, तो आप फ़ाइलों को छोटे बफर के साथ रूबी में विलय कर सकते हैं। यह एक खोल बनाने से बचाता है, और आप बफर आकार को नियंत्रित कर सकते हैं।

यह untested है, लेकिन आप अंदाजा हो:

buffer_size = 4096 
output_file = File.open(final_output_file, 'w') 

Dir["#{processing_directory}/*.csv"].sort_by {|file| [file.count("/"), file]}.each do |file| 
    f = File.open(file) 
    while buffer = f.read(buffer_size) 
    output_file.write(buffer) 
    end 
    f.close 
end 
+0

हाँ, यह काम कर सकता है, मैं कोशिश करूँगा और आपको बता दूंगा। और, क्या आप रूबी 1.9.3 पर स्मृति से संबंधित नोकोगिरी के किसी भी मुद्दे को जानते हैं? हमने हाल ही में रूबी को 1.9.2 से 1.9.3 तक अपग्रेड किया है, मुझे लगता है कि यह भी एक कारण हो सकता है। – Atith

2

मैं एक ही समस्या है, लेकिन cat के बजाय यह sendmail (gem mail) था।

मुझे समाधान hereposix-spawn मणि इंस्टॉल करके समस्या मिली, उदा।

a = (1..500_000_000).to_a 

require 'posix/spawn' 
POSIX::Spawn::spawn('ls') 

इस बार बनाने बच्चे प्रक्रिया सफल होने चाहिए:

gem install posix-spawn 

और यहाँ उदाहरण है।

यह भी देखें: Minimizing Memory Usage for Creating Application Subprocesses ओरेकल में।

2

आप शायद शारीरिक स्मृति से बाहर हैं, इसलिए इसे दोबारा जांचें और अपना स्वैप सत्यापित करें (free -m)। यदि आपके पास स्वैप स्पेस नहीं है, तो create one

अन्यथा यदि आपकी याददाश्त ठीक है, तो त्रुटि संभवतः खोल संसाधन सीमाओं के कारण होती है। आप उन्हें ulimit -a से देख सकते हैं।

उन्हें ulimit द्वारा बदला जा सकता है जो शैल संसाधन सीमा को संशोधित कर सकता है (देखें: help ulimit), उदा।

ulimit -Sn unlimited && ulimit -Sl unlimited 

इन सीमा को लगातार बनाने के लिए, आप निम्नलिखित शेल कमांड द्वारा ulimit सेटिंग फ़ाइल बनाने के द्वारा यह कॉन्फ़िगर कर सकते हैं:

cat | sudo tee /etc/security/limits.d/01-${USER}.conf <<EOF 
${USER} soft core unlimited 
${USER} soft fsize unlimited 
${USER} soft nofile 4096 
${USER} soft nproc 30654 
EOF 

या /etc/sysctl.conf का उपयोग विश्व स्तर पर सीमा बदलने के लिए (man sysctl.conf) उदाहरण के लिए

kern.maxprocperuid=1000 
kern.maxproc=2000 
kern.maxfilesperproc=20000 
kern.maxfiles=50000