2012-05-10 16 views
-2

私はディレクトリ内のファイルを検索し、コンピュータが動作している間無限に実行するpythonスクリプトを持っています。コードは次のとおりです。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()を呼び出します。私はこれで2時間ほど手を触れてきました。

私もやっていることを発見しました。すべての反復で

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:大規模なディレクトリを指し示している間に、2行でコメントアウトしてコメントアウトできます。 – jdi

+0

メモリリークは、私がそれらの行をコメントアウトしているかどうかにかかわらず、また、私がスクリプトを指すディレクトリが空であるかどうかにかかわらず、依然として起こります。今私は何をしますか?私はあなたの助けに感謝しますが、そのままスクリプトを試してもメモリリークの問題は解決しません。 –

0

ここでは、各主要な反復で作成されたインスタンスへの参照が保持されています。

提案:

  1. ドロップクラスと1-2機能ドロップが一致し
  2. を作ります。使用されていませんか?
  3. Windows用のinotify(Linux)などをご覧ください。それは必要なときにのみ指示と行動を見ることができます。連続スキャンん
+0

私はコードを元に戻し、クラスを取り除き、ここで提案された変更を加えました。まだメモリリークがあります。これ以上の提案はありますか? –

+0

@AlexanderAlvonellos:あなたのコード例を、変更したばかりの短いものと置き換えてください。 – jdi

+0

しました。見てみな。 –

関連する問題