Python循环中的MemoryError

2024-10-05 13:20:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我的一个脚本中有一个嵌套的循环,运行时会导致MemoryError。它看起来像这样:

jobRange = range(605)
a = []
for i in jobRange:
    for k in jobRange:
        for j in jobRange:
            if i != k and k != j:
                a.append((i, k, j))

我试图通过使用排列替换可怕的嵌套循环来优化它:

a = []
for p in permutations(jobRange, 3):
    i, k, j = p[0], p[1], p[2]
    a.append((i, k, j))

然而,这并不能解决问题。我仍然得到:

Traceback (most recent call last):
  File "C:/Users/Vejdanpa/PycharmProjects/myProject/Models/test.py", line 10, in <module>
    a.append((i, k, j))
MemoryError

我还尝试了以下超慢代码,只是为了找出这段代码使用了多少内存,从而导致MemoryError

from itertools import permutations
import tracemalloc

tracemalloc.start()
jobRange = range(605)

a = []
for p in permutations(jobRange, 3):
    i, k, j = p[0], p[1], p[2]
    a.append((i, k, j))
    current, peak = tracemalloc.get_traced_memory()
    print(f"Current memory usage: {current / 10 ** 6}MB; Peak: {peak / 10 ** 6}MB")

tracemalloc.stop()

抛出错误之前的最后两行输出是:

Current memory usage: 1022.68617MB; Peak: 1022.686298MB
Current memory usage: 1022.68621MB; Peak: 1022.686338MB
Current memory usage: 1022.68625MB; Peak: 1022.686378MB
Current memory usage: 1022.68629MB; Peak: 1022.686418MB
Current memory usage: 1022.68633MB; Peak: 1022.686458MB
Current memory usage: 1022.68637MB; Peak: 1022.686498MB
Current memory usage: 1022.68641MB; Peak: 1022.686538MB
Current memory usage: 1022.68645MB; Peak: 1022.686578MB
Current memory usage: 1022.68649MB; Peak: 1022.686618MB
Current memory usage: 1022.68653MB; Peak: 1022.686658MB
Traceback (most recent call last):
  File "C:/Users/Vejdanpa/PycharmProjects/myProject/Models/test.py", line 10, in <module>
    a.append((i, k, j))
MemoryError

Process finished with exit code 1

据我所知,这表明阈值以某种方式设置为~1GB,我的程序内存不足,因为它需要更多的1GB。我检查了我的机器的规格: machine specs。这表明我有16GB的ram,据我所知,Python并没有以任何方式限制内存的使用,应该一直运行到内存耗尽为止

我目前正在PyCharm中运行Python3.7中的代码,但在命令行上进行一次简单的尝试就得到了相同的结果

有人能帮助我理解为什么我的python脚本可以使用1GB的内存限制,以及如何增加这种限制吗


Tags: 内存代码in脚本forusagembcurrent
2条回答

我想对@juanpa.arrivillaga的评论加上一句话。
如果你只是想把东西列入清单,你可以选择: list(permutations(jobRange, 3))但这可能不是个好主意,这是有原因的

警告这是反手计算,可能与系统有关

我查找了^{}文档,函数返回的结果数为n! / (n-r)!,在您的例子中是605!/(605-3)!,这简化为605 x 604 x 603
我假设每个int至少是28 bytes,我是通过在我的系统上运行sys.getsizeof(1)得到这个数字的原因:see here

您正在添加一个列表,该列表会随着程序的运行时间而增长。 因此,列表的最终大小,或者更确切地说,列表本身大小的下限(忽略所有其他内容)将是:

605 x 604 x 603 x 28 x 3 ~= 18 509 MB ~= 18.5 GB

这可能会超出你的记忆,而这正是列表的大小

这可能不是对下限的完全准确估计,我发现在Python中对内存使用量的任何估计都非常困难

如果您在Fil memory profiler(https://pythonspeed.com/fil)下运行该程序,它将使用启发式方法在内存耗尽之前转储内存配置文件报告,这样您就可以看到使用了多少内存。请参见此处的示例:https://pythonspeed.com/articles/crash-out-of-memory/

相关问题 更多 >

    热门问题