そこで、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)