Python:MemoryError、OverflowError、即时系统卡住

标签 python python-2.7 for-loop range out-of-memory

最后一天,解决另一个Project Euler我在管理 big for i in range(n) 循环时遇到了麻烦。

我观察到 python 会抛出不同的错误,取决于 x 变量有多大

这是一个mcve示例:

for i in range(x):
    pass

地点:

  • 如果x = 10**20我得到一个OverflowError, 确切地说:OverflowError:range()结果有太多项目

  • 否则如果 x = 10**15 我收到 MemoryError

  • else if x = 10**9 我遇到了instant-system-freeze,我必须硬重置我的电脑。很少情况下,我的电脑不但没有卡住,反而填满了大约 5GB 的交换空间,变得非常慢。

我试图理解 python built-in exception 的含义:

  • OverflowError :

    Raised when the result of an arithmetic operation is too large to be represented. This cannot occur for long integers [...] and for most operations with plain integers, which return a long integer instead. [...]

    这意味着整数永远不应该抛出此异常;此异常的原因是 range() 包含太多项目,因此我认为 10**15 也会抛出相同的异常,但我得到了不同的异常。 ..

  • MemoryError :

    Raised when an operation runs out of memory but the situation may still be rescued (by deleting some objects). [...]

    我应该删除哪个对象来挽救这种情况?它只是退出,所以情况无法挽救......

    如果感觉ram使用量过多,为什么它会以10**9卡住我的电脑?

<小时/>

最后,我的问题是:

为什么我会得到 3 个不同的结果,仅取决于 x 变量中存储的值?

<小时/>

注意:

  • 我知道 xrange 的存在,那没有这个问题,但我的问题是关于 range .
  • 我认为用于引发异常的值可能会发生变化,具体取决于您的硬件。
  • 我的 Python 版本:2.7.6

最佳答案

好吧,range 尝试构建一个整个列表,其中包含与 x 一样多的项目。

对于死亡即时交换情况,您可以估计,假设 64 位和固定的 8 字节整数,x = 10**9 大约值 8 Go。因此,如果您没有更多的内存(考虑到已经使用的 RAM),您就可以明白为什么系统需要交换。

再往下看,如果函数无法分配足够大的 block 来保存结果(在 10**15 的情况下),则可能会引发 MemoryError看起来很大)。

我不知道 range 的实现细节,但它可能使用 OverflowError 来确保元素的绝对最大数量(也许以某种方式以防止 MemoryError,基于实际可用内存)。
正如 @ShadowRanger 的评论中提到的,如果结果的长度无法容纳 size_t 变量(2**31),则会引发 OverflowError > (32 位)或 2**63 (64 位)),因为它无法初始化这样的列表。

正如您所提到的,xrange 不存在此问题,因为它不会生成整个列表,而是在每次迭代时生成一个值。这就是为什么迭代器/生成器具有内存效率。

<小时/>

所以我快速浏览了一下,你可以看到 in the 2.7 source为什么它会抛出OverflowError

关于Python:MemoryError、OverflowError、即时系统卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33149842/

相关文章:

python-2.7 - Python2.7 contextlib.ExitStack 等效项

python - 为什么int.__eq__在python2中似乎没有实现

javascript - JS for循环中的变量取最大值

JavaScript for...in 循环有奇怪的结果

python - 返回函数有问题 - 无法使用递归代码

python - “tensorflow”没有属性 'config'

python - 带回调的扭曲模拟计时器

python - 我如何通过在 python 中使用 re.sub 将 "11 12 13 14"转换为 "12 13 14 15"

matlab - 使用 MATLAB 计算 for 循环内的多个正弦曲线,然后绘制它们

python - 如何将 pandas Series 的 "rows"转换为 DataFrame 的列?