2

そこで、leveldb データベース ( py-leveldb ) を使用してビットコイン ブロックチェーンをアドレスでインデックス付けするための Python スクリプトを作成していますが、クラッシュするまでメモリをどんどん消費し続けます。以下のコード例で動作を再現しました。コードを実行すると、システムで使用可能な RAM が使い果たされ、プロセスが強制終了されるか、「std::bad_alloc」がスローされるまで、ますます多くのメモリが使用され続けます。

私は何か間違ったことをしていますか?バッチ オブジェクトに書き込みを続け、時々コミットしますが、WriteBatch オブジェクトのデータをコミットしても、メモリ使用量が増加し続けます。コミット後に WriteBatch オブジェクトを削除することさえあるので、私が見る限り、メモリリークの原因はこれではありません。

私のコードは間違った方法で WriteBatch を使用していますか、それとも py-leveldb にメモリ リークがありますか?

コードを実行するには py-leveldb が必要です。ここから入手してください: https://pypi.python.org/pypi/leveldb

警告: このコードを長時間実行すると、メモリを使い果たしてしまいます。重要なシステムでは実行しないでください。また、スクリプトが実行されるのと同じフォルダー内のフォルダーにデータを書き込みます。私のシステムでは、このフォルダーには、メモリが使い果たされる前に約 1.5 GB 相当のデータベース ファイルが含まれます (最終的に 3 GB 以上の RAM を消費します)。

コードは次のとおりです。

import leveldb, random, string

RANDOM_DB_NAME = "db-DetmREnTrKjd"
KEYLEN = 10
VALLEN = 30
num_keys = 1000
iterations = 100000000
commit_every = 1000000

leveldb.DestroyDB(RANDOM_DB_NAME)
db = leveldb.LevelDB(RANDOM_DB_NAME)

batch = leveldb.WriteBatch()

#generate a random list of keys to be used
key_list = [''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(KEYLEN)) for i in range(0,num_keys)]

for k in xrange(iterations):
    #select a random key from the key list
    key_index = random.randrange(0,1000)
    key = key_list[key_index]

    try:
        prev_val = db.Get(key)
    except KeyError:
        prev_val = ""

    random_val = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(VALLEN))
    #write the current random value plus any value that might already be there
    batch.Put(key, prev_val + random_val)

    if k % commit_every == 0:
        print "Comitting batch %d/%d..." % (k/commit_every, iterations/commit_every)
        db.Write(batch, sync=True)
        del batch
        batch = leveldb.WriteBatch()

db.Write(batch, sync=True)
4

2 に答える 2

1

http://code.google.com/p/leveldb-py/を使用します

Python leveldb ドライバーのベイクオフに参加するには十分な情報がありませんが、leveldb-py のシンプルさが気に入っています。これは、ctypes を使用した単一の python ファイルです。約 10GB の約 300 万個のキーにドキュメントを保存するために使用しましたが、メモリの問題に気づいたことはありません。

実際の問題: バッチサイズで作業してみてください。

leveldb-py を使用し、すべてのキーに対して put を実行するコードは、20MB 未満のメモリを使用するシステムで正常に動作しました。

ここ ( http://ayende.com/blog/161412/reviewing-leveldb-part-iii-writebatch-isnt-what-you-think-it-is ) から、かなりの数のメモリ コピーが実行されていることがわかります。 leveldb のフード。

于 2013-12-13T15:00:58.870 に答える