如何实现内存密集型python脚本进行测试

时间:2015-05-28 14:21:40

标签: python memory cgroups

我已将cgroups规则应用于特定用户,并且我想测试从上述用户运行的程序的内存是否已按预期限制。我尝试使用以下脚本:

import string
import random

if __name__ == '__main__':
    d = {}
    i = 0;
    for i in range(0, 100000000):
        val = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(200)) # generate ramdom string of size 200
        d[i] = val
        if i % 10000 == 0:
            print i

当我通过ps命令监控进程时,结果是%MEM增加到4.8并且在两个cgroups服务打开和关闭时都没有改变:

$ ps aux | grep mem_intensive.py
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
jason    11531 88.5  4.8 3312972 3191236 pts/0 R+   22:16   0:07 python mem_intensive.py

在这种情况下,总内存为62GB,因此其中4.8%约为3GB。我将限制设置为4GB,而不在此用户上运行任何其他进程。

那么有谁能让我对这个有问题的python脚本有所了解?提前谢谢。

3 个答案:

答案 0 :(得分:1)

如果要查看cgroup是否有效,只需将限制设置为100MB并尝试启动脚本。关键是要确定一个大限制是否比一个小限制更好或更差 - 你只是想确保一个限制被强制执行。为此,一个小的限制就足够了。

为确保dict按预期增长,您可以使用此问题的答案打印它的大小:Memory-usage of dictionary in Python?

答案 1 :(得分:1)

我已经玩了一些你的脚本,它保持增长,虽然很慢。瓶颈是使用random.choice。如果你想快速填充内存,生成随机性对你不利。所以只使用固定字符串会很快耗尽内存。如果使用以下内容,在想要了解它的增长情况时,您可能会在time.sleep()之后抛出print

if __name__ == '__main__':
    d = {}
    i = 0;
    for i in range(0, 100000000):
        d[i] = 'A'*1024
        if i % 10000 == 0:
            print(i)

更快地填充内存:

只是一个单行:

['A'*1024 for _ in xrange(0, 1024*1024*1024)]

答案 2 :(得分:0)

range在内存中构造一个列表,然后循环遍历,xrange创建一个生成器,它是一个对象,它像序列一样提供循环但不在内存中构建该序列。对于短距离,rangexrange之间没有什么区别,但是对于大范围,引用Python文档有显着差异:https://docs.python.org/2/library/functions.html#xrange

在Python 3中,xrange提供的功能成为内置范围的默认功能。由于这一点,以及Python 2中xrange固有的内存优势,我发现Python 2到3兼容层将Python 2 range函数映射到xrange相反,在引擎盖下。