内存错误和列表限制?
我需要生成很大很大的矩阵(马尔可夫链),用于科学研究。我进行的计算结果有20301个元素(相当于我矩阵的一行)。我需要把这些数据都放在内存里,以便进行下一步的马尔可夫计算,不过如果需要的话,我也可以把它们存到其他地方(比如文件),虽然这样会让我的马尔可夫链的处理速度变慢。我的电脑配置是:Bi-xenon 6核/12线程,每个12GB内存,操作系统是win64。
Traceback (most recent call last):
File "my_file.py", line 247, in <module>
ListTemp.append(calculus)
MemoryError
计算结果的例子:9.233747520008198e-102(是的,这个数比1/9000还小)
在存储第19766个元素时出现了错误:
ListTemp[19766]
1.4509421012263216e-103
如果我继续往下做
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
ListTemp[19767]
IndexError: list index out of range
所以在第19767次循环时,这个列表出现了内存错误。
问题:
列表有没有内存限制?是“列表限制”还是“全局脚本限制”?
有什么办法可以绕过这些限制?你有什么想法吗?
使用numpy和python64会有帮助吗?它们的内存限制是多少?其他语言呢?
4 个回答
Python本身并没有限制内存的使用。不过,如果你的电脑内存用完了,就会出现一个叫做MemoryError
的错误。你提到你的list
里有20301个元素。对于简单的数据类型(比如int
),这个数量看起来不算多,不应该导致内存错误。但如果每个元素都是占用大量内存的对象,那你可能就真的内存不够用了。
至于IndexError
错误,可能是因为你的ListTemp
只有19767个元素(索引从0到19766),而你试图访问超出最后一个元素的部分。
要避免这些问题,具体该怎么做还得看你想实现什么功能。使用numpy
可能会有帮助。看起来你在存储大量数据,可能并不需要在每个阶段都存储所有数据。但具体情况还得了解更多才能判断。
你看到的 MemoryError
错误是因为你的电脑内存不够用。可能是因为 Windows 对每个程序限制了 2GB 的内存(这适用于 32位程序),或者你的电脑本身可用的内存太少了。(这个 链接 是之前的一个相关问题)。
如果你使用的是 64 位的 Windows,可以通过使用 64 位的 Python 来突破 2GB 的限制。
至于 IndexError
错误,是因为 Python 在计算整个数组之前就遇到了 MemoryError
,这也是内存的问题。
要解决这个问题,你可以尝试使用 64 位的 Python,或者更好的方法是找个办法把结果写入文件。为此,可以看看 numpy 的 内存映射数组。
这样你就可以把所有的计算结果放到这些数组里,实际的数据会写入硬盘,只有一小部分会保存在内存中。
首先,可以看看这两个链接:Python数组能有多大? 和 Numpy,处理长数组的问题
其次,真正的限制来自于你电脑的内存有多少,以及你的系统是如何管理内存的。其实,Python对每个列表没有固定的大小限制,它会一直使用内存,直到内存用完为止。这里有两种情况:
- 如果你在使用一个较旧的操作系统,或者这个系统限制了程序使用的内存量,你可能需要增加Python程序可以使用的内存。
- 可以把列表分成小块来处理。比如,先处理列表的前1000个元素,把它们保存到硬盘上,然后再处理接下来的1000个。这样在使用的时候,每次只加载一小块,避免内存用完。这种方法其实和数据库处理超出内存的数据是一样的。