2009-02-18 14 views
7

मेरा प्रोग्राम फ़ाइल हैंडल लीक प्रतीत होता है। मैं कहां से पता लगा सकता हूं?पायथन में फ़ाइल हैंडल लीक का पता लगाएं?

मेरा प्रोग्राम कुछ अलग-अलग स्थानों में फ़ाइल हैंडल का उपयोग करता है-बाल प्रक्रियाओं से आउटपुट, ctypes एपीआई (छविमैजिक) फाइलें खोलता है, और उनकी प्रतिलिपि बनाई जाती है।

यह shutil.copyfile में दुर्घटनाग्रस्त हो जाता है, लेकिन मुझे पूरा यकीन है कि यह जगह लीक नहीं है।

Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
    File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 874, in main 
    magpy.run_all() 
    File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 656, in run_all 
    [operation.operate() for operation in operations] 
    File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 417, in operate 
    output_file = self.place_image(output_file) 
    File "C:\Python25\Lib\site-packages\magpy\magpy.py", line 336, in place_image 
    shutil.copyfile(str(input_file), str(self.full_filename)) 
    File "C:\Python25\Lib\shutil.py", line 47, in copyfile 
    fdst = open(dst, 'wb') 
IOError: [Errno 24] Too many open files: 'C:\\Documents and Settings\\stuart.axon\\Desktop\\calzone\\output\\wwtbam4\\Nokia_NCD\\nl\\icon_42x42_V000.png' 
Press any key to continue . . . 
+0

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

उत्तर

3

ls -l /proc/$pid/fd/ से उत्पादन पर देखो (, अपनी प्रक्रिया की पीआईडी ​​प्रतिस्थापन निश्चित रूप से) को देखने के लिए जो फ़ाइलों खुले हैं [या Win32 पर,, Process Explorer का उपयोग खुली फ़ाइलों सूची]; फिर पता लगाएं कि आपके कोड में आप उन्हें खोल रहे हैं, और close() को कॉल किया जा रहा है। (हां, कचरा कलेक्टर अंततः चीजों को बंद कर देगा, लेकिन एफडीएस से बाहर निकलने से बचने के लिए यह हमेशा तेज़ नहीं होता है)।

कचरा संग्रह को रोकने वाले किसी भी परिपत्र संदर्भों की जांच करना भी एक अच्छा अभ्यास है। (चक्र कलेक्टर अंततः इनका निपटान करेगा - लेकिन फ़ाइल डिस्क्रिप्टर थकावट से बचने के लिए यह अक्सर पर्याप्त नहीं हो सकता है; मुझे इसे व्यक्तिगत रूप से काट दिया गया है)।

+0

मुझे लगता है कि यह एक Win32 बॉक्स है, c: \ python25 पथ दिए गए हैं। – twk

+0

कचरा संग्रह: क्या पाइथन में कुछ जेएस कार्यान्वयन में चक्र कलेक्टर की तरह कुछ नहीं है? –

+0

@ स्टुअर्ट - यह एक चक्र कलेक्टर के साथ संदर्भित गिनती जीसी है, लेकिन चक्र कलेक्टर रैम खत्म होने से पहले अनिवार्य रूप से अनियंत्रित फ़ाइल ऑब्जेक्ट्स को बंद करने के लिए पर्याप्त रूप से पर्याप्त नहीं चलता है। –

3

Process Explorer का उपयोग करें, अपनी प्रक्रिया का चयन करें, देखें-> लोअर फलक व्यू-> हैंडल - फिर देखें कि जगह से क्या लगता है - आमतौर पर समस्या के बहुत से समान या समान फाइलें खुली होती हैं।

3

lsof -p <process_id> फ्रीबीएसडी सहित कई यूनिक्स जैसी प्रणालियों पर अच्छी तरह से काम करता है।

+0

जाहिर है सवाल विंडोज के बारे में है। – Olli

3

मुझे इसी तरह की समस्याएं थीं, उपप्रोसेसर के दौरान फाइल डिस्क्रिप्टर से बाहर चल रही थी। पोपेन() कॉल। मैं क्या हो रहा है पर डिबग करने के लिए निम्न स्क्रिप्ट का प्रयोग किया:

import os 
import stat 

_fd_types = (
    ('REG', stat.S_ISREG), 
    ('FIFO', stat.S_ISFIFO), 
    ('DIR', stat.S_ISDIR), 
    ('CHR', stat.S_ISCHR), 
    ('BLK', stat.S_ISBLK), 
    ('LNK', stat.S_ISLNK), 
    ('SOCK', stat.S_ISSOCK) 
) 

def fd_table_status(): 
    result = [] 
    for fd in range(100): 
     try: 
      s = os.fstat(fd) 
     except: 
      continue 
     for fd_type, func in _fd_types: 
      if func(s.st_mode): 
       break 
     else: 
      fd_type = str(s.st_mode) 
     result.append((fd, fd_type)) 
    return result 

def fd_table_status_logify(fd_table_result): 
    return ('Open file handles: ' + 
      ', '.join(['{0}: {1}'.format(*i) for i in fd_table_result])) 

def fd_table_status_str(): 
    return fd_table_status_logify(fd_table_status()) 

if __name__=='__main__': 
    print fd_table_status_str() 

आप इस मॉड्यूल आयात और fd_table_status_str() फोन अपने कोड में विभिन्न बिंदुओं पर फ़ाइल वर्णनकर्ता तालिका स्थिति लॉग ऑन कर सकते हैं।

इसके अलावा, सुनिश्चित करें कि subprocess.Popen उदाहरण नष्ट हो गए हैं। विंडोज़ में पॉपन उदाहरणों के संदर्भों को ध्यान में रखते हुए जीसी को चलने से रोकें। और यदि उदाहरण रखा जाता है, तो संबंधित पाइप बंद नहीं होते हैं। अधिक जानकारी here

+0

"इसके अलावा, सुनिश्चित करें कि subprocess.Popen उदाहरण नष्ट हो गए हैं। विंडोज़ में पॉपन उदाहरणों के संदर्भों को रखने से जीसी को चलने से रोकते हैं। और यदि उदाहरण रखा जाता है, तो संबंधित पाइप बंद नहीं होते हैं। अधिक जानकारी" - यह एक विशेष कारण है मेरे मामले में subjuct। हम इसे pOpenInstansec [index] = none के माध्यम से हल करते हैं - बनाई गई प्रक्रिया से संबंधित सभी हैंडल को हल करने के लिए (जैसे stdin \ etc।) – N0dGrand87

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