如何填满 90% 的空闲内存?

Edu*_*scu 211 memory testing

我想做一些低资源测试,为此我需要有 90% 的可用内存已满。

我怎样才能在*nix系统上做到这一点?

tkr*_*nwa 183

stress-ng是一个工作负载生成器,它模拟 POSIX 系统上的 cpu/mem/io/hdd 压力。这个调用应该在 Linux < 3.14 上起作用:

stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Run Code Online (Sandbox Code Playgroud)

对于 Linux >= 3.14,您可以MemAvailable改为使用来估计新进程的可用内存而无需交换:

stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Run Code Online (Sandbox Code Playgroud)

/proc/meminfofree(1)/ vm_stat(1)/etc调整调用。如果你需要它便携。有关进一步的使用示例,另请参阅压力 ng参考 wiki

  • 压力 --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.097;}' &lt; /proc/meminfo)k --vm-keep -m 10 (3认同)
  • 大部分MemFree由操作系统保留,所以我使用MemAvailable代替。这使我在 Cent OS 7 上的使用率为 92%。 `stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' &lt; /proc/meminfo)k --vm -保留-m 1` (2认同)
  • 作为补充说明,同时提供`--vm 1 和--vm-keep` 非常重要。简单的 `--vm-bytes` 什么都不做,你可能会误以为你可以根据需要/想要分配尽可能多的内存。在我尝试通过分配 256G 内存来检查自己之前,我对此有所了解。这不是答案中的缺陷,它提供了正确的标志,只是额外的警告。 (2认同)

小智 94

您可以将 C 程序写入malloc()所需的内存,然后使用mlock()以防止内存被换出。

然后让程序等待键盘输入,并解锁内存,释放内存并退出。

  • 很久以前我不得不测试类似的用例。我观察到,在您向该内存写入内容之前,它不会被实际分配(即,直到发生页面错误)。我不确定 mlock() 是否会处理这个问题。 (30认同)
  • 您可能必须实际写入内存,如果您只对其进行 malloc,内核可能会过度使用。如果配置为,例如 Linux 将让 malloc 成功返回,而实际上没有释放内存,并且仅在写入时才实际分配内存。见 http://www.win.tue.nl/~aeb/linux/lk/lk-9.html (11认同)
  • @Sebastian:`calloc` 会遇到同样的问题 IIRC。所有内存都将指向同一个只读归零页面。在您尝试写入它之前,它实际上不会被分配(因为它是只读的,所以它不起作用)。真正确定我知道的唯一方法是对整个缓冲区进行`memset`。有关更多信息,请参阅以下答案 http://stackoverflow.com/a/2688522/713554 (9认同)
  • 代码的一些[灵感](http://stackoverflow.com/a/4735795/543411)。此外,我认为*您不需要解锁/释放内存*。当您的进程结束时,操作系统将为您执行此操作。 (3认同)
  • 我同意@siri;但是,这取决于您使用的 UNIX 变体。 (2认同)

Luc*_*Luc 75

如果您有基本的 GNU 工具(headtail)或 Linux 上的 BusyBox,您可以这样做来填充一定数量的空闲内存

</dev/zero head -c BYTES | tail
</dev/zero head -c 5000m | tail #~5GB, portable
</dev/zero head -c 5G    | tail #5GiB on GNU (not busybox)
cat /dev/zero | head -c 5G | tail #Easier notation; does the same thing
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为 tail 需要将当前行保留在内存中,以防它成为最后一行。线,读取/dev/zero其输出仅空字节并且没有换行符,将是无限长的,但由不限headBYTES字节,因而tail将只使用的内存。要获得更精确的数量,您需要检查系统上使用了多少 RAMheadtail它本身,然后减去它。

要完全快速耗尽 RAM,您可以删除限制head部分:

tail /dev/zero
Run Code Online (Sandbox Code Playgroud)

如果你还想添加一个持续时间,这可以很容易地完成bash(在 中不起作用sh):

cat <( </dev/zero head -c 500m) <(sleep SECONDS) | tail
Run Code Online (Sandbox Code Playgroud)

<(command)件事似乎鲜为人知,但通常非常有用,更多信息在这里:http : //tldp.org/LDP/abs/html/process-sub.html

cat命令将等待输入完成直到退出,并且通过保持其中一个管道打开,它将保持tail活动状态。

如果您有pv并想慢慢增加 RAM 使用

</dev/zero head -c TOTAL | pv -L BYTES_PER_SEC | tail
</dev/zero head -c 1000m | pv -L 10m | tail
Run Code Online (Sandbox Code Playgroud)

后者将以每秒 10 MB 的速度使用多达 1 GB。作为额外的奖励,pv显示当前的使用率和到目前为止的总使用率。当然,这也可以使用以前的变体来完成:

</dev/zero head -c 500m | pv | tail
Run Code Online (Sandbox Code Playgroud)

只需插入| pv |零件即可显示当前状态(默认情况下为吞吐量和总数)。

如果你没有/dev/zero设备,标准yestr工具,可以替代:yes | tr \\n x | head -c BYTES | tailyes输出“是” ES无限量,tr替代了这样的换行,一切都变成一个巨大的线和尾需要保持所有在内存中)。
另一种更简单的替代方法是使用dddd if=/dev/zero bs=1G of=/dev/null在 GNU 和 BusyBox 上使用 1GB 内存,但在一个内核上使用 100% CPU。
最后,如果您head不接受后缀,您可以计算内联字节数,例如 50 兆字节:head -c $((1024*1024*50))


感谢falstaff贡献了一个更简单、更广泛兼容的变体(如 BusyBox)。


为什么是另一个答案?接受的答案建议安装一个包(我敢打赌,每个芯片组都有一个版本,不需要包管理器);最高投票的答案建议编译 C 程序(我没有安装编译器或工具链来为您的目标平台进行编译);第二个投票最高的答案建议在 VM 中运行应用程序(是的,让我通过 USB 或其他方式将这款手机的内部 SD 卡添加到虚拟机中并创建一个虚拟机映像);第三个建议修改引导序列中的某些内容,但不会按需要填充 RAM;第四个仅适用于 /dev/shm 挂载点 (1) 存在且 (2) 很大(重新挂载需要 root);第五个结合了上面的许多没有示例代码;第六个是一个很好的答案,但在提出我自己的方法之前我没有看到这个答案,所以我想我会添加我自己的,也是因为如果你没有看到 memblob 线实际上是问题的关键,那么记住或输入它会更短;第七次再次不回答问题(使用 ulimit 来限制进程);第八个尝试让您安装python;第九个认为我们都非常缺乏创造力,最后第十个编写了自己的 C++ 程序,这导致了与最高投票答案相同的问题。


Dav*_*ett 49

我建议运行一个内存有限的虚拟机并测试软件,这比尝试填充主机上的内存更有效。

该方法还有一个优点,如果低内存情况导致其他地方出现 OOM 错误并挂起整个操作系统,您只能挂起您正在测试的 VM,而不是您可能正在运行其他有用进程的机器。

此外,如果您的测试不是 CPU 或 IO 密集型的,您可以在一系列具有各种低内存大小的 VM 上同时运行测试实例。


小智 36

来自此 HN 评论:https : //news.ycombinator.com/item? id =6695581

只需通过 dd 或类似方式填写 /dev/shm 即可。

swapoff -a
dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
Run Code Online (Sandbox Code Playgroud)

  • 并非所有 *nix 都有 /dev/shm。任何更便携的想法? (9认同)
  • 如果安装了`pv`,它有助于查看计数:`dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024` (2认同)

小智 32

  1. 运行Linux;
  2. 使用mem=nn[KMG]内核引导参数引导

(查看linux/Documentation/kernel-parameters.txt了解详细信息)。


小智 21

我保留了一个函数来在我的 dotfiles 中做类似的事情。 https://github.com/sagotsky/.dotfiles/blob/master/.functions#L248

function malloc() {
  if [[ $# -eq 0 || $1 -eq '-h' || $1 -lt 0 ]] ; then
    echo -e "usage: malloc N\n\nAllocate N mb, wait, then release it."
  else 
    N=$(free -m | grep Mem: | awk '{print int($2/10)}')
    if [[ $N -gt $1 ]] ;then 
      N=$1
    fi
    sh -c "MEMBLOB=\$(dd if=/dev/urandom bs=1MB count=$N) ; sleep 1"
  fi
}
Run Code Online (Sandbox Code Playgroud)


小智 20

一个简单的python解决方案怎么样?

#!/usr/bin/env python

import sys
import time

if len(sys.argv) != 2:
    print "usage: fillmem <number-of-megabytes>"
    sys.exit()

count = int(sys.argv[1])

megabyte = (0,) * (1024 * 1024 / 8)

data = megabyte * count

while True:
    time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

  • 这可能会很快被换掉,对内存压力几乎没有实际影响(除非你也填满所有的交换区,这通常需要一段时间) (8认同)

小智 12

如果存在 ramfs 呢?挂载它并复制一个大文件?如果没有/dev/shm也没有 ramfs - 我猜是一个基于某些输入值执行大型 malloc 的小型 C 程序?可能必须在具有大量内存的 32 位系统上一次运行几次。


小智 9

如果要测试内存有限的特定进程,最好使用ulimit限制可分配内存的数量。

  • 实际上这在linux上不起作用(不知道其他* nixes)。`man setrlimit`: `RLIMIT_RSS 指定进程驻留集的限制(以页为单位)(驻留在 RAM 中的虚拟页数)。此限制仅在 Linux 2.4.x 中有效,x &lt; 30,并且仅影响对指定 MADV_WILLNEED 的 madvise(2) 调用。` (2认同)

小智 7

我认为这是一个提出错误问题的案例,而人们在竞争最有创意的答案时却淹没了理智。如果只需要模拟OOM条件,则不需要填满内存。只需使用自定义分配器并在一定数量的分配后使其失败。这种方法似乎对SQLite足够好。


ron*_*ron 6

我需要 90% 的可用内存已满

万一还没有足够的答案,我没有看到的是做 ramdisk 或者技术上来说是tmpfs。这会将 RAM 映射到 Linux 中的一个文件夹,然后您只需在其中创建或转储任意大小的文件即可占用您想要的 RAM 量。一个缺点是您需要成为 root 才能使用 mount 命令

# first as root make the given folder, however you like where the tmpfs mount is going to be.

mkdir /ramdisk

chmod 777 /ramdisk

mount -t tmpfs -o size=500G tmpfs /ramdisk

# change 500G to whatever size makes sense; in my case my server has 512GB of RAM installed.
Run Code Online (Sandbox Code Playgroud)

获取或复制或创建合理大小的文件;例如创建一个 1GB 文件

cp my1gbfile /ramdisk/file001
cp my1gbfile /ramdisk/file002

# do 450 times; 450 GB of 512GB approx 90%
Run Code Online (Sandbox Code Playgroud)

用于free -g观察分配了多少 RAM。

注意:例如,拥有 512GB 物理 RAM,如果您的 tmpfs 超过 512GB,它将可以工作,并允许您通过分配 100% 的 RAM 来冻结/崩溃系统。因此,建议只使用 tmpfs 足够多的 RAM,以便为系统留下一些合理的空闲量。

要创建给定大小的单个文件:

truncate -s 450G my450gbfile

# man truncate

# also dd works well

dd if=/dev/zero of=my456gbfile bs=1GB count=456
Run Code Online (Sandbox Code Playgroud)