簡體   English   中英

增加 Python 中的內存限制?

[英]Increasing memory limit in Python?

我目前正在使用一個函數制作極長的字典(用於比較 DNA 字符串),有時我會遇到 MemoryError。 有沒有辦法為 Python 分配更多內存,以便它可以一次處理更多數據?

Python 不會限制程序的內存使用。 它將根據您的程序需要分配盡可能多的內存,直到您的計算機內存不足。 您最多可以做的是將限制減少到固定的上限。 這可以通過resource模塊來完成,但這不是你要找的。

您需要考慮使您的代碼對內存/性能更友好。

如果您使用 linux,您可以嘗試使用 Swap 擴展內存- 一種運行需要比機器中安裝的內存更多的程序的簡單方法。

但是,更好的方法是更新程序以在可能的情況下以塊的形式處理數據或擴展機器中的內存,因為使用此方法(使用較慢的磁盤設備)會降低性能。

Python 有 MomeoryError,這是您使用resource包手動定義的系統 RAM 實用程序的限制。

使用插槽定義類使 python 解釋器知道類的屬性/成員是固定的。 並且可以節省大量內存!

您可以使用__slot__減少 python 解釋器的 dict 創建。 這將告訴解釋器不要在內部創建 dict 並重用相同的變量。

如果您的 Python 進程消耗的內存會隨着時間的推移而繼續增長。 這似乎是以下各項的組合:

  • Python 中的 C 內存分配器如何工作。 這本質上是內存碎片,因為除非整個內存塊都未使用,否則分配不能稱為“空閑”。 但是內存塊的使用通常與您正在創建和使用的對象不完全一致。
  • 使用多個小字符串來比較數據。 內部使用稱為實習的過程,但創建多個小字符串會給解釋器帶來負擔。

最好的方法是創建工作線程或單線程池來完成您的工作並使工作線程/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/

嘗試將您的 py 從 32 位更新到 64 位。

只需在命令行中輸入python ,您就會看到您的 python 是哪個。 32位python中的內存非常低。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM