我目前正在使用一个函数制作极长的字典(用于比较 DNA 字符串),有时我会遇到 MemoryError。 有没有办法为 Python 分配更多内存,以便它可以一次处理更多数据?
Python 不限制程序的内存使用。它将根据您的程序需要分配尽可能多的内存,直到您的计算机内存不足。您最多可以做的就是将限制降低到固定的上限。这可以通过
resource
模块来完成,但这不是您要找的。
你需要考虑让你的代码对内存/性能更友好。
Python 有 MomeoryError,这是你的系统 RAM 的限制,你已经用
resource
包手动定义了它。
用 slots 定义你的类让 python 解释器知道你的类的属性/成员是固定的。并且可以节省大量内存!
您可以使用
__slot__
减少 python 解释器创建的字典。这将告诉解释器不要在内部创建字典并重用相同的变量。
如果你的python进程消耗的内存会随着时间持续增长。这似乎是以下组合:
最好的方法是创建工作线程或单线程池来完成您的工作,并使 worker/kill 无效以释放工作线程中附加/使用的资源。
下面的代码创建单线程工作者:
__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/
虽然 Python 不限制程序的内存使用,但 OS 系统对每个程序都有动态的 CPU 和 RAM 限制,以保证整机的良好性能和性能。
我致力于图形分形生成,它需要尽可能多的十亿个字符数组来加快生成速度。 而且我发现操作系统设置的每个 python 程序都有一个软限制,这会降低机器上算法的实际性能。
当您增加 RAM 内存和 CPU 使用率(缓冲区、循环、线程)时,进程的总速度会降低。有用的线程数量和线程频率降低,导致结果处理时间变长。但是,如果您将资源使用量减少到旧配置的 50...75%(缓冲区大小更小、循环更小、线程更少、频率更低或线程计时器更长)并将任务拆分为多个部分,然后运行多个控制台 python 程序同时处理所有任务部分。它会花费更少的时间来完成,当你检查 CPU 和 RAM 使用情况时,它会比旧方法单 python 程序多线程高得多。
就是说当我们做一个处理高性能、高速度和海量数据处理的程序时,我们需要设计具有多个后台程序的程序,并且每个后台程序都有多个线程运行。此外,将磁盘空间结合到进程中,而不是仅使用内存。
即使达到最大物理内存,与通过将大数据拆分为多个部分来处理大数据相比,一次处理大数据会更慢并限制应用程序。
可选,如果您的程序是特殊应用程序,请考虑:
通过创建多个后台程序,它允许您创建不需要用户安装图形卡的高速图形应用程序。如果您希望您的程序轻松分发给集成 AI 和昂贵计算能力的最终用户,这也是一个不错的选择。升级 4-16GB 范围内的 RAM 比显卡更便宜。
尝试将你的 py 从 32 位更新到 64 位。
只需在命令行中输入
python
,你就会看到你的python是哪个。 32 位 python 中的内存非常低。