現在、非常に長い辞書(DNA文字列の比較に使用)を作成する関数を使用しており、MemoryErrorが発生する場合があります。 Pythonより多くのデータを一度に処理できるように、より多くのメモリを割り当てる方法はありますか?
Pythonには、システムの制限であるMomeoryErrorがありますRAM util resource
パッケージで手動で定義したユーティリティ。
slotsを使用してクラスを定義すると、pythonインタープリターは、クラスの属性/メンバーが修正されたことを認識します。また、メモリを大幅に節約することができます。
pythonインタープリターは__slot__
を使用することにより、dictの作成を減らすことができます。これにより、インタープリターは内部でdictを作成せず、同じ変数を再利用します。
pythonプロセスによって消費されるメモリが時間とともに増大し続ける場合、これは次の組み合わせのようです:
最善の方法は、ワーカースレッドまたはシングルスレッドプールを作成して作業を行い、ワーカー/キルを無効にして、ワーカースレッドでアタッチ/使用されているリソースを解放することです。
以下のコードはシングルスレッドワーカーを作成します:
__slot__ = ('dna1','dna2','lock','errorResultMap')
lock = threading.Lock()
errorResultMap = []
def process_dna_compare(dna1, dna2):
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
futures = {executor.submit(getDnaDict, lock, dna_key): dna_key for dna_key in dna1}
'''max_workers=1 will create single threadpool'''
dna_differences_map={}
count = 0
dna_processed = False;
for future in concurrent.futures.as_completed(futures):
result_dict = future.result()
if result_dict :
count += 1
'''Do your processing XYZ here'''
logger.info('Total dna keys processed ' + str(count))
def getDnaDict(lock,dna_key):
'''process dna_key here and return item'''
try:
dataItem = item[0]
return dataItem
except:
lock.acquire()
errorResultMap.append({'dna_key_1': '', 'dna_key_2': dna_key_2, 'dna_key_3': dna_key_3,
'dna_key_4': 'No data for dna found'})
lock.release()
logger.error('Error in processing dna :'+ dna_key)
pass
if __name__ == "__main__":
dna1 = '''get data for dna1'''
dna2 = '''get data for dna2'''
process_dna_compare(dna1,dna2)
if errorResultMap != []:
''' print or write to file the errorResultMap'''
以下のコードは、メモリ使用量を理解するのに役立ちます:
import objgraph
import random
import inspect
class Dna(object):
def __init__(self):
self.val = None
def __str__(self):
return "dna – val: {0}".format(self.val)
def f():
l = []
for i in range(3):
dna = Dna()
#print “id of dna: {0}”.format(id(dna))
#print “dna is: {0}”.format(dna)
l.append(dna)
return l
def main():
d = {}
l = f()
d['k'] = l
print("list l has {0} objects of type Dna()".format(len(l)))
objgraph.show_most_common_types()
objgraph.show_backrefs(random.choice(objgraph.by_type('Dna')),
filename="dna_refs.png")
objgraph.show_refs(d, filename='myDna-image.png')
if __name__ == "__main__":
main()
メモリ使用量の出力:
list l has 3 objects of type Dna()
function 2021
wrapper_descriptor 1072
dict 998
method_descriptor 778
builtin_function_or_method 759
Tuple 667
weakref 577
getset_descriptor 396
member_descriptor 296
type 180
スロットの詳細については、次をご覧ください。 https://elfsternberg.com/2009/07/06/python-what-the-hell-is-a-slot/