【发布时间】:2015-03-22 10:06:14
【问题描述】:
我正在尝试将 2 个元素增加到 30 个元素的列表,但出现内存错误。为什么这样?是否超出了python列表的最大限制?
m=[None]*(2**30)
【问题讨论】:
我正在尝试将 2 个元素增加到 30 个元素的列表,但出现内存错误。为什么这样?是否超出了python列表的最大限制?
m=[None]*(2**30)
【问题讨论】:
是的,Python 列表可以容纳多少元素是有限制的,请参阅sys.maxsize。但是,您没有击中它;很少有机器有足够的内存来容纳这么多物品。
您正在尝试创建一个包含 1073741824 个引用的列表;每个引用也占用内存。这取决于您的操作系统多少,但通常对于 32 位系统来说这将是 4 个字节,对于 64 位操作系统来说是 8 个字节,其中 2^30 个元素需要 4 GB 或 8GB 的内存,仅用于列表参考。
4GB 加上其他元素已经很容易超过大多数当前操作系统允许单个进程在内存中使用的容量。
在我的 Mac OS X 机器上(使用 64 位操作系统),sys.maxsize 是 2^63,列表中的 Python 对象引用占用 8 个字节:
>>> import sys
>>> sys.maxsize
9223372036854775807
>>> sys.maxsize.bit_length()
63
>>> sys.getsizeof([]) # empty list overhead
72
>>> sys.getsizeof([None]) - sys.getsizeof([]) # size of one reference
8
因此,要创建一个包含 sys.maxsize 元素的列表,您需要 64 个 exbibytes 内存,仅供参考。这超出了 64 位计算机所能处理的范围(practical maximum is about 16 exbibytes)。
所有这些都忽略了您在列表中引用的对象将占用的内存占用。 None 是一个单例,所以它只会占用固定数量的内存。但大概您打算在该列表中存储一些else,在这种情况下,您也需要考虑到这一点。
一般来说,您永远不应该需要创建这么大的列表。使用不同的技术;例如,使用字典创建稀疏结构,我怀疑您是否打算直接在算法中处理所有那些 2^30 索引。
【讨论】:
您正在尝试在此处创建一个巨大的列表,但您没有足够的可用 RAM 来执行此操作。您需要多少 RAM?
在我的机器上大约有 8Gb。你可以在你的机器上找到 None 的大小:
import sys
sys.getsizeof(None) # 16 here
但是对于一个列表,你可以这样近似:
sys.getsizeof([None] * (2**20)) # 8388680
并希望 2**30 大约需要 2**10 倍,您最终会得到大约 8Gb 的 8388680 * 2**10。
【讨论】:
None 是一个单例,只有 一个 这样的对象占用这 16 个字节。您可以根据需要创建尽可能多的引用,然后是 references 占用内存。 64 位机器上的引用通常为 8 个字节,具体取决于操作系统。