2012-05-10 4 views
-2

디렉토리에서 파일을 검색하고 컴퓨터가 실행되는 동안 무한대로 수행하는 python 스크립트가 있습니다. 다음은 코드입니다.파이썬 프로그래밍 메모리 누출? 아마도? 파일 검색 및 파괴 스크립트

import fnmatch 
import os 
import shutil 
import datetime 
import time 
import gc 
# This is a python script that removes the "conflicted" copies of 
# files that dropbox creates when one computer has the same copy of 
# a file as another computer. 
# Written by Alexander Alvonellos 
# 05/10/2012 

class cleanUpConflicts: 
    rootPath = 'D:\Dropbox' 
    destDir = 'D:\Conflicted' 
    def __init__(self): 
     self.removeConflicted() 
     return 

    def cerr(message): 
     f = open('./LOG.txt', 'a') 
     date = str(datetime.datetime.now()) 
     s = '' 
     s += date[0:19] #strip floating point 
     s += ' : ' 
     s += str(message) 
     s += '\n' 
     f.write(s) 
     f.close() 
     del f 
     del s 
     del date 
     return 

    def removeConflicted(self): 
     matches = [] 
     for root, dirnames, filenames in os.walk(self.rootPath): 
      for filename in fnmatch.filter(filenames, '*conflicted*.*'): 
       matches.append(os.path.join(root, filename)) 
       cerr(os.path.join(root, filename)) 
       shutil.move(os.path.join(root, filename), os.path.join(destDir, filename)) 
     del matches 
      return 

def main(): 
    while True: 
     conf = cleanUpConflicts() 
     gc.collect() 
     del conf 
     reload(os) 
     reload(fnmatch) 
     reload(shutil) 
     time.sleep(10) 
    return 

main() 

어쨌든. 10 초마다 거의 1 메가를 추가하는 메모리 누수가 있습니다. 나는 왜 메모리가 할당 해제되지 않는지 이해하지 못한다. 그것의 끝에,이 원본은 노력조차없이 계속 기억의 작살을 먹을 것이다. 이것은 실망 스럽다. 누구든지 어떤 조언이 있으십니까? 나는 모든 것을 시도했다, 나는 생각한다. 여기

여기에 제안 된 일부 변경 한 후 업데이트 된 버전의 :이 문제에 대한 몇 가지 연구 노력을 한 적이

import fnmatch 
import os 
import shutil 
import datetime 
import time 
import gc 
import re 
# This is a python script that removes the "conflicted" copies of 
# files that dropbox creates when one computer has the same copy of 
# a file as another computer. 
# Written by Alexander Alvonellos 
# 05/10/2012 

rootPath = 'D:\Dropbox' 
destDir = 'D:\Conflicted' 

def cerr(message): 
    f = open('./LOG.txt', 'a') 
    date = str(datetime.datetime.now()) 
    s = '' 
    s += date[0:19] #strip floating point 
    s += ' : ' 
    s += str(message) 
    s += '\n' 
    f.write(s) 
    f.close() 
    return 


def removeConflicted(): 
    for root, dirnames, filenames in os.walk(rootPath): 
     for filename in fnmatch.filter(filenames, '*conflicted*.*'): 
      cerr(os.path.join(root, filename)) 
      shutil.move(os.path.join(root, filename), os.path.join(destDir, filename)) 
return 


def main(): 
    #while True: 
    for i in xrange(0,2): 
     #time.sleep(1) 
     removeConflicted() 
     re.purge() 
     gc.collect() 
    return 
main() 

을하고있다으로 fnmatch 버그,있을 수 있습니다처럼 보인다 사용 후 제거되지 않는 정규식 엔진. 그래서 re.purge()를 호출합니다. 나는 이것을 두어 시간 동안 어루 만졌다. 모든 반복에

print gc.collect() 

반환 0 :

은 또한 일을 발견했습니다.

누구든지 나를 떨어 뜨린 사람은 분명히 착각합니다. 여기에 정말 도움이 필요해. 여기에 내가 이야기하고있는 링크가 있습니다 : Why am I leaking memory with this python loop?

+0

왜 다시로드하고 있습니까? –

+0

10 초마다 해당 모듈을 다시로드하지 않으려 고합니다. 이유가 없습니다. 또한 모든 del 문을 필요로하지 않아야합니다 (누수가있는 경우 왜 시도 할 수 있는지 알 수 있지만) 모든 함수의 끝에서 확실히 return을 필요로하지 않습니다. – Peter

+0

이 누수의 출처를 추적하려고하기 때문에 다시로드하고 있습니다. 다른 제안이 있으십니까? 이것이 어디에서 왔는지에 대한 포인터를 얻으면 코드에 몇 가지 변경을 가할 것입니다. –

답변

0

귀하의 코드는이 단축 될 수있는 연속적인 스캔하지 : 처리 할 파일이 없을 경우 메모리 누수가 발생할 경우

import fnmatch 
import os 
import shutil 
import datetime 
import time 

ROOT_PATH = r'D:/Dropbox' 
DEST_DIR = r'D:/Conflicted' 

def cerr(message, log): 
    date = str(datetime.datetime.now()) 
    msg = "%s : %s\n" % (date[0:19], message) 
    log.write(msg) 

def removeConflicted(log): 
    for root, dirnames, filenames in os.walk(ROOT_PATH): 
     for filename in fnmatch.filter(filenames, '*conflicted*.*'): 
      # 1: comment out this line and check for leak 
      cerr(os.path.join(root, filename), log) 
      # 2: then comment out this line instead and check 
      shutil.move(
       os.path.join(root, filename), 
       os.path.join(DEST_DIR, filename)) 


def main(): 
    with open('./LOG.txt', 'a') as log: 
     while True: 
      print "loop" 
      removeConflicted(log) 
      time.sleep(10) 

if __name__ == "__main__": 
    main() 

참조. 즉, 빈 디렉터리를 가리키고 이동을 수행 할 때 누출이 발생하는지 확인합니다.
re.purge() 또는 gc 모듈을 사용하지 않아도됩니다.

+0

나는 그것을 시도하고 당신에게 돌아 가자. 도와 줘서 고마워. –

+0

@AlexanderAlvonellos : 두 줄의 주석을 달았습니다. 큰 디렉토리를 가리키며 주석 처리를 시도 할 수 있습니다. – jdi

+0

메모리 누수는 내가 그 라인을 주석 처리하고, 스크립트가 가리키고있는 디렉토리가 비 었는지에 관계없이 여전히 발생합니다. 지금 무엇을해야합니까? 도움을 주셔서 감사하지만, 그대로 스크립트를 사용해 보더라도 메모리 누수 문제는 해결되지 않습니다. –

0

추측 컨데, 어떤 것은 각각의 주 반복으로 생성 된 인스턴스에 대한 참조를 유지합니다.

제안 :

  1. 클래스를 삭제하고
  2. 드롭 일치 1-2 기능
  3. 을; 사용하지 않습니까?
  4. Windows 용 inotify (Linux) 또는 유사품을보십시오. 그것은 필요할 때만 지시와 행동을 볼 수 있습니다.
+0

코드를 재실행하고, 클래스를 제거하고, 여기에 제안 된 변경 사항을 적용했습니다. 이벤트보기 기능을 제외한 모든 것입니다. 여전히 메모리 누수가 있습니다. 더 이상의 제안? –

+0

@AlexanderAlvonellos : 코드 예제를 방금 변경 한 짧은 문장으로 대체하십시오. – jdi

+0

방금 ​​했어요. 확인 해봐. –