增加 Python 中的内存限制?

问题描述 投票:0回答:4

我目前正在使用一个函数制作极长的字典(用于比较 DNA 字符串),有时我会遇到 MemoryError。 有没有办法为 Python 分配更多内存,以便它可以一次处理更多数据?

python memory-management
4个回答
28
投票

Python 不限制程序的内存使用。它将根据您的程序需要分配尽可能多的内存,直到您的计算机内存不足。您最多可以做的就是将限制降低到固定的上限。这可以通过

resource
模块来完成,但这不是您要找的。

你需要考虑让你的代码对内存/性能更友好。


1
投票

Python 有 MomeoryError,这是你的系统 RAM 的限制,你已经用

resource
包手动定义了它。

slots 定义你的类让 python 解释器知道你的类的属性/成员是固定的。并且可以节省大量内存!

您可以使用

__slot__
减少 python 解释器创建的字典。这将告诉解释器不要在内部创建字典并重用相同的变量。

如果你的python进程消耗的内存会随着时间持续增长。这似乎是以下组合:

  • Python 中的 C 内存分配器是如何工作的。这本质上是内存碎片,因为除非整个内存块未被使用,否则分配不能调用“free”。但是内存块的使用通常与您正在创建和使用的对象并不完全一致。
  • 使用多个小字符串来比较数据。内部使用称为实习的过程,但创建多个小字符串会给解释器带来负担。

最好的方法是创建工作线程或单线程池来完成您的工作,并使 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/


0
投票

虽然 Python 不限制程序的内存使用,但 OS 系统对每个程序都有动态的 CPU 和 RAM 限制,以保证整机的良好性能和性能。

我致力于图形分形生成,它需要尽可能多的十亿个字符数组来加快生成速度。 而且我发现操作系统设置的每个 python 程序都有一个软限制,这会降低机器上算法的实际性能。

  • 当您增加 RAM 内存和 CPU 使用率(缓冲区、循环、线程)时,进程的总速度会降低。有用的线程数量和线程频率降低,导致结果处理时间变长。但是,如果您将资源使用量减少到旧配置的 50...75%(缓冲区大小更小、循环更小、线程更少、频率更低或线程计时器更长)并将任务拆分为多个部分,然后运行多个控制台 python 程序同时处理所有任务部分。它会花费更少的时间来完成,当你检查 CPU 和 RAM 使用情况时,它会比旧方法单 python 程序多线程高得多。

  • 就是说当我们做一个处理高性能、高速度和海量数据处理的程序时,我们需要设计具有多个后台程序的程序,并且每个后台程序都有多个线程运行。此外,将磁盘空间结合到进程中,而不是仅使用内存。

  • 即使达到最大物理内存,与通过将大数据拆分为多个部分来处理大数据相比,一次处理大数据会更慢并限制应用程序。

  • 可选,如果您的程序是特殊应用程序,请考虑:

    1. 将图形卡计算能力应用到程序中,Intel图形使用OpenGL和图形加速或NVIDIA使用CUDA。
    2. 切换到 OS 和 python 64 位
    3. 切换回较旧的操作系统(但不要太旧):Windows 7 64 位或更旧的 Ubuntu、linux。因为更高的操作系统具有更昂贵的豪华功能和服务消耗计算机资源。使用 SSD 驱动器并从 Windows 11,10 切换回 7 时,您将看到 python 能力和运行速度的显着提高。
    4. 如果您使用 Windows,请切换到安全模式。
  • 通过创建多个后台程序,它允许您创建不需要用户安装图形卡的高速图形应用程序。如果您希望您的程序轻松分发给集成 AI 和昂贵计算能力的最终用户,这也是一个不错的选择。升级 4-16GB 范围内的 RAM 比显卡更便宜。


-1
投票

尝试将你的 py 从 32 位更新到 64 位。

只需在命令行中输入

python
,你就会看到你的python是哪个。 32 位 python 中的内存非常低。

© www.soinside.com 2019 - 2024. All rights reserved.