Python内存错误,当运行在一个包含百万词汇表的词汇表上时

Python内存错误,当运行在一个包含百万词汇表的词汇表上时,python,memory,dictionary,for-loop,Python,Memory,Dictionary,For Loop,我的对象是一个字典,里面有大约一百万个对象({}和{},有时是{{},{{},{},{}…} 在运行使用FOR循环的项时,我发现以下行有一个错误: lines = fp.readlines() MemoryError: Fatal Python error: PyEval_RestoreThread: NULL tstate 我对这个物体有5到6个动作要做。 尝试对迭代循环执行“一体式”操作会触发此错误。 在单独的循环上运行(每个循环执行一个操作)-前两个循环工作得很好,但是,总是在第三次运行

我的对象是一个字典,里面有大约一百万个对象({}和{},有时是{{},{{},{},{}…}

在运行使用FOR循环的项时,我发现以下行有一个错误:

lines = fp.readlines()
MemoryError: Fatal Python error: PyEval_RestoreThread: NULL tstate
我对这个物体有5到6个动作要做。 尝试对迭代循环执行“一体式”操作会触发此错误。 在单独的循环上运行(每个循环执行一个操作)-前两个循环工作得很好,但是,总是在第三次运行循环时(大约在80000次迭代之后),Python崩溃(如上所述的内存错误)

我改变了动作顺序-意味着改变了循环顺序,它总是在第三个“for”循环失败

我试着使用一台更强更快的机器,但仍然会出现这些错误

请告知


p.S

我想这对你的RAM来说太多了。如果可能的话,你真的应该在一个for循环中进行操作,并优化你的迭代以提高内存效率

fp.readlines()
嗯,它一次读取文件的所有行,因此它的所有内容都在内存中。我不知道细节,也不知道如何将文件内容转换为字典。但是如果它依赖于文件中的行,你可以简单地在文件上迭代,每迭代一步都会产生一行

for line in fp:
    # ...
但是,如果您再次将文件中的所有信息存储在字典中,您将再次面临相同的问题

通过检查(如果可能的话)重复项来优化存储在内存中的数据是CPU密集型的,但可能需要降低内存使用率


在这两个代码段执行相同的操作后,一致性存储和生成器之间的差异应该很明显,但前者比后者占用更多内存。请注意,
iterate\u to
range/xrange
函数完全相同,只是用于说明目的

def iterate_to(num):
    list_ = []
    for i in xrange(num):
        list_.append(i)
    return list_

def operate_on(num):
    list_ = []
    for i in iterate_to(num):
        x = (i ** i + 5) / (i * 2)
        list_.append(x)
    return list_

print sum(operate_on(1000000))
虽然
sum
函数对
operate\u on
返回的列表中的每个元素进行求和,但每个1000000条目的两个列表(!!)在内存中是一致的。您可能已经认为这样做可以提高内存效率

def iterate_to(num):
    for i in xrange(num):
        yield i

def operate_on(num):
    for i in iterate_to(num):
        x = (i ** i + 5) / (i * 2)
        yield x

print sum(operate_on(1000000))
在本例中,表达式
yield
用于使
迭代到
操作函数都成为生成器函数。迭代时,每个迭代步骤都直接计算迭代的下一个元素,而不是依赖于先前构造的项集合。

更多关于生成器的信息。

我想这对你的RAM来说太多了。如果可能的话,你真的应该在一个for循环中进行操作,并优化你的迭代以提高内存效率

fp.readlines()
嗯,它一次读取文件的所有行,因此它的所有内容都在内存中。我不知道细节,也不知道如何将文件内容转换为字典。但是如果它依赖于文件中的行,你可以简单地在文件上迭代,每迭代一步都会产生一行

for line in fp:
    # ...
但是,如果您再次将文件中的所有信息存储在字典中,您将再次面临相同的问题

通过检查(如果可能的话)重复项来优化存储在内存中的数据是CPU密集型的,但可能需要降低内存使用率


在这两个代码段执行相同的操作后,一致性存储和生成器之间的差异应该很明显,但前者比后者占用更多内存。请注意,
iterate\u to
range/xrange
函数完全相同,只是用于说明目的

def iterate_to(num):
    list_ = []
    for i in xrange(num):
        list_.append(i)
    return list_

def operate_on(num):
    list_ = []
    for i in iterate_to(num):
        x = (i ** i + 5) / (i * 2)
        list_.append(x)
    return list_

print sum(operate_on(1000000))
虽然
sum
函数对
operate\u on
返回的列表中的每个元素进行求和,但每个1000000条目的两个列表(!!)在内存中是一致的。您可能已经认为这样做可以提高内存效率

def iterate_to(num):
    for i in xrange(num):
        yield i

def operate_on(num):
    for i in iterate_to(num):
        x = (i ** i + 5) / (i * 2)
        yield x

print sum(operate_on(1000000))
在本例中,表达式
yield
用于使
迭代到
操作函数都成为生成器函数。迭代时,每个迭代步骤都直接计算迭代的下一个元素,而不是依赖于先前构造的项集合。

有关生成器的详细信息。

这很可能是内存问题-python 2.*无法使用超过2Gb的RAM。这可能是由于垃圾收集延迟造成的。请安装gc库,并在密集处理程序块之后(例如,在每次FOR循环之后)尝试手动调用垃圾收集。在填充后,从文件对象中清除内存带文件内容的r字典。无论如何,请从使用top命令或任务管理器查看内存消耗开始。

这很可能是内存问题-python 2.*无法使用超过2Gb的RAM。这可能是由于垃圾收集延迟造成的。请安装gc库,并在密集处理垃圾后尝试手动调用垃圾收集,例如,在每次FOR循环之后。在用文件内容填充字典后,从文件对象中清除内存。无论如何,从使用top命令或任务管理器查看内存消耗开始。

gc.colletc()并没有解决我的问题。导致内存使用量减少的更改在一个巨大的时间内覆盖了我的1M对象{Dictionary}并将其中的一些对象“移动”到特殊的[列表]对象中。 内存使用率仍然很高(约1.7GB),但目前脚本正在运行,不再崩溃。 谢谢大家的回答,我从这些回复中了解到了这一点,这非常有帮助。

gc.colletc()并没有解决我的问题。导致内存使用减少的变化是在一个巨大的{Dictionary}中对我的1M对象进行了更改,并将其中一些对象“移动”到特殊的[list]对象中。 内存使用率仍然很高(约1.7GB),但目前脚本正在运行,不再崩溃。
谢谢大家的回答,我从这些回复中学到了这一点,非常有帮助。

这看起来像是一个线程错误。