常驻集大小(RSS)限制无效。

20

在运行Ubuntu 10.04和2.6.32-22-generic内核的机器上遇到以下问题:设置进程的Resident Set Size(RSS)限制似乎没有任何效果。我目前使用以下Python代码来设置限制:

import resource
# (100, 100) is the (soft, hard) limit. ~100kb.
resource.setrlimit(resource.RLIMIT_RSS, (100, 100))
memory_sink = ['a']*10000000   # this should fail

列表memory_sink每次都成功。当我用top查看RSS使用情况时,我可以很容易地使进程使用1GB的RAM,这意味着限制没有起作用。这个内核或发行版不支持RSS限制吗?如果有帮助的话,resource.RLIMIT_NPROC(用户进程限制)是有效的。

4个回答

19

你可以使用cgroups来实现这一点。我在博客中详细阐述了这个方法。但简短的版本(经过Ubuntu 11.04测试)是:

  • 安装cgroup-bin软件包。

  • 编辑/etc/cgconfig.config文件并创建一个受限制的内存组。例如,我添加了:

    group limited {
      memory {
        memory.limit_in_bytes = 50M;
      }
    }
    
  • 运行

    $ sudo restart cgconfig
    $ sudo chown -R jlebar /sys/fs/cgroup/memory/limited
    $ cgexec -g memory:limited your/program
    

当我要求我的程序仅使用50M时,观察到RSS为93M,但这对我来说不是问题,因为我的目标只是让程序分页。

cgclassify也允许您在运行的进程上附加限制。请注意,对于RSS,这只适用于在限制生效后分配的内存。


1
在Ubuntu 11.10上,配置文件的位置已更改为:/etc/cgconfig.conf - maxschlepzig
2
在Ubuntu 10.04上,当我尝试运行sudo restart cgconfig命令时,只会收到错误消息“restart: Unknown job: cgconfig”。:( - zrajm
1
我没有root权限。我还能使用吗? - gerrit
对于较新的Ubuntu(我在16.04上尝试过):https://askubuntu.com/a/848022/65575 (cgconfigparser -l /etc/cgconfig.config) - nh2

18

getrlimit manpage 中获取:

RLIMIT_RSS
Specifies the limit (in pages) of  the  process's  resident  set
(the  number of virtual pages resident in RAM).  This limit only
has effect in Linux 2.4.x, x < 30, and there only affects  calls
to madvise(2) specifying MADV_WILLNEED.

似乎Linux内核2.6不支持此功能。


1
我已经无数次谷歌了 man 手册,但错过了其中有这个条款的部分。在我的机器上简单地输入“man getrlimit”就足够了。谢谢! - BrainCore

4

与此相关的限制是虚拟内存或地址空间(RLIMIT_AS) - 这确实起作用。这允许在没有外部工具的情况下限制Python进程和子进程的内存。

>>> size = 50*1024*1024 # In bytes
>>> resource.setrlimit(resource.RLIMIT_AS, (size, resource.RLIM_INFINITY))
>>> a = 'a' * size
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError

来自man页面

RLIMIT_AS。进程虚拟内存(地址空间)的最大大小,以字节为单位。

这里有一个很好的解释Resident Set和VM size之间的区别- Linux内存管理中的RSS和VSZ是什么


2
当我尝试使用RLIMIT_AS时,即使分配的内存远低于限制,我仍然会遇到MemoryError错误。请参见此问题 - gerrit
@gerrit 这可能是因为 RLIMIT_AS “包括进程可以访问的所有内存,包括交换出去但未使用的内存、已分配但未使用的内存以及来自共享库的内存。” https://dev59.com/oGsz5IYBdhLWcg3weHkA#21049737 - moi

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接