【问题标题】:Running a Python process with limited memory运行内存有限的 Python 进程
【发布时间】:2020-04-15 01:50:26
【问题描述】:

我们有一个 Python 命令行实用程序,它调用 API 来下载大文件,我们想看看程序在内存有限(约 1 GB 或更少)的机器上运行时的行为。

这样做的一个选项是使用虚拟化层(Docker 容器或 Vagrant 虚拟盒)来创建具有指定内存量的操作系统。但我对不同的方法感兴趣。

我想知道是否有办法限制 Python 进程的可用内存量,以便我可以运行命令行界面来进行 API 调用,但将其限制为(比如说)512 MB 的最大值内存来测试内存不足问题。

寻找适用于 Mac OS X(运行 10.14+)或 Linux 的解决方案。

【问题讨论】:

标签: python memory out-of-memory


【解决方案1】:

使用 setrlimit 设置最大内存大小

根据@Alexis Drakopoulos's answerresource 模块可用于设置 Python 脚本使用的最大虚拟内存量,但需要注意的是 此方法仅适用于基于 Linux 的系统,并且确实不适用于基于 BSD 的系统,例如 Mac OS X

要修改限制,请将以下调用添加到 Python 脚本中的 setrlimit

resource.setrlimit(resource.RLIMIT_AS, (soft_lim, hard_lim))

(其中软/硬限制是以字节为单位 - 它们的值通常相等)。

快速示例

下面是一个快速示例,它将内存限制为大约 1 MB,然后由于内存错误而无法导入 pandas

$ python
Python 3.6.9 (default, Nov  7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import resource

>>> print(resource.getrlimit(resource.RLIMIT_AS))
(-1, -1)

>>> resource.setrlimit(resource.RLIMIT_AS, (1000,1000))

>>> import pandas as pd
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/vagrant/.local/lib/python3.6/site-packages/pandas/__init__.py", line 11, in <module>
  File "/home/vagrant/.local/lib/python3.6/site-packages/numpy/__init__.py", line 142, in <module>
  File "/home/vagrant/.local/lib/python3.6/site-packages/numpy/core/__init__.py", line 24, in <module>
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 779, in get_code
  File "<frozen importlib._bootstrap_external>", line 487, in _compile_bytecode
MemoryError
MemoryError

为什么这在 BSD 系统上不起作用?

如果您查看getrlimitsetrlimit 的手册页,您将看到RLIMIT_* 变量的列表——但该列表在BSD 和Linux 之间是不同的。 Linux getrlimit/setrlimit man page 列出了RLIMIT_AS,但BSD getrlimit/setrlimit man page 没有列出任何用于控制内存量的RLIMIT 变量。因此,即使在 Mac OS X 上的 resource 模块中定义了 resource.RLIMIT_AS,设置它对内核或进程可用的内存量没有影响。

另见What do the two numbers returned by Python's resource.RLIMIT_VMEM (or resource.RLIMIT_AS) mean?

【讨论】:

    【解决方案2】:

    如果您真的想在 Python 本身中执行此操作,您可以尝试查看resource doc,它可以使用setrlimit() 来设置那里列出的资源的限制,其中内存就是其中之一。不确定这是否有帮助。

    【讨论】:

    • 这绝对是我正在寻找的方法,但如果我运行(在 Mac OS X 10.14 或 Ubuntu 18.04 上使用 Python 3.7)python -c 'import resource; print(resource.getrlimit(resource.RLIMIT_VMEM))' 我会得到AttributeError: module 'resource' has no attribute 'RLIMIT_VMEM'
    • Per this answer 我尝试使用 resource.RLIMIT_AS 而不是 resource.RLIMIT_VMEM,这适用于 Mac OS X 和 Ubuntu。
    猜你喜欢
    • 2023-04-05
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2011-01-24
    • 2015-07-27
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多