使用Python消耗内存

56

我正在尝试创建一个能够“有意地”立即消耗特定数量RAM的应用程序。 例如,我想消耗512 MB的RAM,那么这个应用程序将直接消耗512 MB。

我在网上搜索了一下,大多数人都使用while循环来填充变量或数据以填满RAM。但我认为这是一种较慢的方法,而且可能不准确。

我正在寻找一个关于内存管理的Python库,并发现了这些http://docs.python.org/library/mmap.html。但我无法弄清如何使用这些库来一次性占用RAM空间。

我曾经看到过一个内存消耗应用程序,但不知道它们是如何编写的...

那么,有没有其他更好的建议可以立即使用随机数据填充RAM? 或者我应该只使用while循环手动填充数据,但使用多线程使其更快?


4
你为什么不创建一个适当大小的随机数组? - user616736
数据 = 'X' * int((所需字节数-Python开销) * 某个常量) - Jochen Ritzel
4
@yoda: 那就这么简单,肯定没那么容易。 - sehe
@yoda:是的,它可以工作...但你知道吗,我刚刚重新启动了我的电脑...我不知道它会消耗多少资源.... :) - Yeo
谢谢尤达 :) 已经理解并解决了实验 ;) 非常感谢 :) - Yeo
我没有测试任何脚本,因为我的电脑没有关机的选项(当它卡住时):) - Nouman
6个回答

68

可能有一种简单的方法:

some_str = ' ' * 512000000

在我的测试中,似乎效果还不错。

编辑: 在 Python 3 中,你可能想使用 bytearray(512000000) 替代。


2
决定块大小(例如1024),而不是请求一个巨大的字符串,请求许多小字符串。 - salezica
我尝试了但仍然有问题... 我将其分成两个部分并成功加载了前512 MB,但是后面的512 MB没有加载成功... - Yeo
3
Python无法分配超过操作系统允许的内存限制的内存空间。 - Wooble

14

使用类似于以下结构的语句,您将无法分配所有可用的内存:

s = ' ' * BIG_NUMBER

最好使用附加列表的方式,就像这样:

a = []
while True:
    print len(a)
    a.append(' ' * 10**6)

这里是一段较长的代码,它可以更好地说明内存分配限制:

import os
import psutil

PROCESS = psutil.Process(os.getpid())
MEGA = 10 ** 6
MEGA_STR = ' ' * MEGA

def pmem():
    tot, avail, percent, used, free = psutil.virtual_memory()
    tot, avail, used, free = tot / MEGA, avail / MEGA, used / MEGA, free / MEGA
    proc = PROCESS.get_memory_info()[1] / MEGA
    print('process = %s total = %s avail = %s used = %s free = %s percent = %s'
          % (proc, tot, avail, used, free, percent))

def alloc_max_array():
    i = 0
    ar = []
    while True:
        try:
            #ar.append(MEGA_STR)  # no copy if reusing the same string!
            ar.append(MEGA_STR + str(i))
        except MemoryError:
            break
        i += 1
    max_i = i - 1
    print 'maximum array allocation:', max_i
    pmem()

def alloc_max_str():
    i = 0
    while True:
        try:
            a = ' ' * (i * 10 * MEGA)
            del a
        except MemoryError:
            break
        i += 1
    max_i = i - 1
    _ = ' ' * (max_i * 10 * MEGA)
    print 'maximum string allocation', max_i
    pmem()

pmem()
alloc_max_str()
alloc_max_array()

这是我收到的输出:

process = 4 total = 3179 avail = 2051 used = 1127 free = 2051 percent = 35.5
maximum string allocation 102
process = 1025 total = 3179 avail = 1028 used = 2150 free = 1028 percent = 67.7
maximum array allocation: 2004
process = 2018 total = 3179 avail = 34 used = 3144 free = 34 percent = 98.9

4
我不得不将一行代码更改为 tot,avail,percent,used,free,active,inactive,buffers,cached = psutil.virtual_memory(),以避免出现 ValueError: too many values to unpack - Fernando Correia
@FernandoCorreia 看起来Bryan的答案解决了这个问题,并且让它在Python3上运行(从print语句中的括号判断)。 - mwfearnley

9
x = bytearray(1024*1024*1000)

占用大约1GB的内存空间


类似于之前的答案 https://dev59.com/6m015IYBdhLWcg3w6QHA#6317871 - Yeo
最简单的解决方案 - user1720897

2
该函数将在字节对象列表中分配内存。列表中的每个项目实际上是独特的且长度相同。该函数还记录其分配情况。我已经测试过它可以分配高达3.7 TiB的内存。它使用humanfriendly包,但如果您不需要它,可以删除其使用。
它确实使用了循环,但至少它允许您自选每次分配多少内存。例如,您可以为multiplier_per_allocation使用8倍的值。
import logging
import secrets
from typing import Optional

from humanfriendly import format_size

log = logging.getLogger(__name__)


def fill_memory(*, num_unique_bytes_per_allocation: int = 1024, multiplier_per_allocation: int = 1024 ** 2, max_allocations: Optional[int] = None) -> None:
    """Allocate available memory into a list of effectively unique bytes objects.

    This function is for diagnostic purposes.

    :param num_unique_bytes_per_allocation: Each allocation is created by multiplying a random sequence of bytes of this length.
    :param multiplier_per_allocation: Each allocation is created by multiplying the random sequence of bytes by this number.
    :param max_allocations: Optional number of max allocations.
    """
    # Ref: https://dev59.com/6m015IYBdhLWcg3w6QHA#66109163/
    num_allocation_bytes = num_unique_bytes_per_allocation * multiplier_per_allocation
    log.info(
        f"Allocating cumulative instances of {num_allocation_bytes:,} bytes ({format_size(num_allocation_bytes)}) each. "
        f"Each allocation uses {num_unique_bytes_per_allocation:,} unique bytes ({format_size(num_unique_bytes_per_allocation)}) "
        f"with a multiplier of {multiplier_per_allocation:,} ({format_size(multiplier_per_allocation)})."
    )

    # Allocate memory
    allocated = []
    num_allocation = 1
    while True:
        unique_bytes_for_allocation = secrets.token_bytes(num_unique_bytes_per_allocation)
        allocated.append(unique_bytes_for_allocation * multiplier_per_allocation)
        num_total_bytes_allocated = num_allocation * num_allocation_bytes
        log.info(f"Used a total of {num_total_bytes_allocated:,} bytes ({format_size(num_total_bytes_allocated)}) via {num_allocation:,} allocations.")
        if max_allocations and (max_allocations == num_allocation):
            break
        num_allocation += 1

示例输出:

>>> import logging
>>> logging.basicConfig(level=logging.INFO)

>>> fill_memory()

INFO:Allocating cumulative instances of 1,073,741,824 bytes (1 GiB) each. Each allocation uses 1,024 unique bytes (1 KiB) with a multiplier of 1,048,576 (1 MiB).
INFO:Used a total of 1,073,741,824 bytes (1 GiB) via 1 allocations.
INFO:Used a total of 2,147,483,648 bytes (2 GiB) via 2 allocations.
INFO:Used a total of 3,221,225,472 bytes (3 GiB) via 3 allocations.
INFO:Used a total of 4,294,967,296 bytes (4 GiB) via 4 allocations.

2
这是一个对我有用的 markolopa的答案版本:
import os
import psutil

PROCESS = psutil.Process(os.getpid())
MEGA = 10 ** 6
MEGA_STR = ' ' * MEGA


def pmem():
    try:
        tot, avail, percent, used, free, active, inactive, buffers = psutil.virtual_memory()
    except ValueError:
        tot, avail, percent, used, free, active, inactive, buffers, cached, shared = psutil.virtual_memory()
    tot, avail, used, free = tot / MEGA, avail / MEGA, used / MEGA, free / MEGA
    proc = PROCESS.memory_info()[1] / MEGA
    print('process = %s total = %s avail = %s used = %s free = %s percent = %s'
          % (proc, tot, avail, used, free, percent))


def alloc_max_array():
    i = 0
    ar = []
    while True:
        try:
            #ar.append(MEGA_STR)  # no copy if reusing the same string!
            ar.append(MEGA_STR + str(i))
        except MemoryError:
            break
        i += 1
    max_i = i - 1
    print('maximum array allocation:', max_i)
    pmem()


def alloc_max_str():
    i = 0
    while True:
        try:
            a = ' ' * (i * 10 * MEGA)
            del a
        except MemoryError:
            break
        i += 1
    max_i = i - 1
    _ = ' ' * (max_i * 10 * MEGA)
    print('maximum string allocation', max_i)
    pmem()

pmem()
alloc_max_str()
alloc_max_array()

1

您可以通过执行以下命令来分配大量的内存:

while True:
    for i in range(0,100000000):
        Gig = 1024*1024*1024*2#A Gig multiplied by 2
        a = 999999999999999999999 * (i * Gig)
        a = a * i
        print str(a)*2

将其保存在.pyw文件中以进行后台RAM分配。 如果不会导致电脑死机,请尝试增加变量a的值。 要停止它:

#First we send signals
os.system("TASKKILL /im pythonw.exe")
os.system("TASKKILL /im python.exe") 
print "Forcefull termination"
#Now we forcefully terminate
#pythonw.exe if running in idle or background
os.system("TASKKILL /im python.exe /f")
os.system("TASKKILL /im pythonw.exe /f")
os.system("pause")

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