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

评论

它真的必须在任何* nix系统上工作吗?

您可以创建内存有限的VM(使用docker,vagrant或类似工具),而不是突出填充内存吗?
@abendigo对于QA,此处介绍的许多解决方案很有用:对于没有特定平台的通用OS,VM或内核引导参数可能有用,但是对于嵌入式系统,您知道目标系统的内存规格后,去填充可用内存。

如果其他人对这里的评分感到有些震惊:meta.unix.stackexchange.com/questions/1513/…?

另请参阅:unix.stackexchange.com/a/1368/52956

#1 楼

Stress-ng是一种工作负载生成器,可模拟POSIX系统上的cpu / mem / io / hdd压力。在Linux <3.14上,此调用应该可以解决问题:对于Linux> = 3.14,可以使用MemAvailable来估计新进程的可用内存,而无需交换: br />
stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n",  * 0.9;}' < /proc/meminfo)k --vm-keep -m 1


/proc/meminfo / free(1) / etc适应vm_stat(1)调用。如果您需要便携式的话。

评论


压力--vm-bytes $(awk'/ MemFree / {printf“%d \ n”,$ 2 * 0.097;}'
–罗伯特
15年10月23日在16:47

大多数MemFree由操作系统保留,因此我改用MemAvailable。这使我在Cent OS 7上的使用率为92%。压力--vm-bytes $(awk'/ MemAvailable / {printf“%d \ n”,$ 2 * 0.98;}'
– kujiy
18-2-8在0:36



众所周知,MemAvailable被添加到“估计有多少内存可用于启动新应用程序而无需交换”,请参见git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ …和git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/…

– tkrennwa
18-2-8在9:11



补充说明一下,同时提供--vm 1和--vm-keep非常重要。简单地--vm-bytes不会执行任何操作,您可能会误以为您可以根据需要/想要分配尽可能多的内存。我对此有所了解,直到我尝试通过分配256G内存来检查自己的状况。这不是答案中的缺陷,它提供了正确的标志,只是额外的警告。

–雏鸟
19 Mar 26 '19 at 12:56

这就是为什么有-m 1的原因。根据压力手册页,-m N是--vm N的缩写:spawn N worker在malloc()/ free()上旋转

– tkrennwa
19-3-27在3:03



#2 楼

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

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

评论


很久以前,我不得不测试类似的用例。我观察到,除非您向该内存中写入内容,否则它实际上不会被分配(即直到发生页面错误)。我不确定mlock()是否会解决这个问题。

– Poorna
13年8月8日在13:31

我同意@siri;但是,这取决于您使用的是哪个变体UNIX。

–安东尼
13年8月8日在13:34

该代码的一些启发。此外,我认为您不需要解锁/释放内存。流程结束后,操作系统将为您执行此操作。

–塞巴斯蒂安
2013年11月8日13:44



您可能必须实际写入内存,如果仅对内存进行malloc,则内核可能会过量使用。如果配置为例如Linux将让malloc成功返回而实际上没有可用的内存,并且仅在写入内存时才实际分配内存。参见win.tue.nl/~aeb/linux/lk/lk-9.html

–伯克·弗洛伊德·汉森(Bjarke Freund-Hansen)
13年8月8日14:32

@Sebastian:calloc将遇到相同的问题IIRC。所有内存将仅指向相同的只读清零页面。在尝试写入之前,它实际上不会被分配(由于它是只读的,因此不会起作用)。真正确定自己知道的唯一方法是对整个缓冲区进行memset。有关更多信息,请参见以下答案stackoverflow.com/a/2688522/713554

–狮子座
13年11月8日在16:43

#3 楼

如果您在Linux上具有基本的GNU工具(headtail)或BusyBox,则可以这样做以填充一定数量的可用内存: ,以防万一是最后一行。从/dev/zero读取的行仅输出空字节而没有换行符,它将无限长,但是受head限制为BYTES字节,因此tail将仅使用那么多的内存。要获取更精确的数量,您需要检查headtail本身在系统上使用了多少内存,并将其减去。
要完全快速耗尽RAM,可以删除限制的head部分:
</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

如果您还想添加一个持续时间,则可以在bash中很容易做到(在sh中不起作用):通常非常有用,有关更多信息,请参见:http://tldp.org/LDP/abs/html/process-sub.html
<(command)命令将等待输入完成直到退出,并保留其中一个管道打开,它将使cat保持活动状态。
如果您拥有tail并想要缓慢增加RAM使用量:
tail /dev/zero

后者将以每10兆字节的速度使用多达1 GB的数据。第二。另外,pv将显示当前使用率和到目前为止的总使用率。当然,这也可以使用以前的变体来完成:
只需插入pv部分,即可显示当前状态(默认情况下的吞吐量和总计)。
如果没有| pv |设备,标准的/dev/zeroyes工具可能会替代:tryes | tr \n x | head -c BYTES | tail输出无限数量的“是”,yes替代换行符,以便所有内容变为一条巨大的行,并且尾部需要将所有内容保留在内存中)。
另一种更简单的选择是使用trdd在GNU和BusyBox上使用1GB内存,但在一个内核上使用100%CPU。
最后,如果dd if=/dev/zero bs=1G of=/dev/null不接受后缀,则可以计算内联字节数,例如50兆字节:head

感谢falstaff提供了更简单,更广泛兼容的变体(例如BusyBox)。可接受的答案建议安装一个软件包(我敢保证每个芯片组都有一个版本,而无需软件包管理器);票数最高的答案建议编译C程序(我没有安装可用于目标平台的编译器或工具链);第二个投票最高的答案建议在VM中运行该应用程序(是的,让我通过USB或其他方式在这部手机的内部sdcard上添加dd并创建一个virtualbox映像);第三个建议在启动顺序中修改某些内容,使其无法按需填充RAM;仅当/ dev / shm挂载点(1)存在且(2)很大时(挂载需要root),第四个才有效;第五部分结合了上面的许多内容而没有示例代码;第六个是一个很好的答案,但是在提出自己的方法之前我没有看到这个答案,所以我想我要添加自己的答案,这也是因为如果您看不到膜状线,记住或输入的时间会更短实际上是问题的症结所在;第七个再次不回答问题(使用ulimit限制进程);第八种尝试让您安装python;第九个人认为我们都很缺乏创造力,最后第十个人编写了自己的C ++程序,该程序导致了与最高投票答案相同的问题。

评论


可爱的解决方案。唯一的毛病是该构造的退出代码为1,因为grep找不到匹配项。 stackoverflow.com/questions/6550484/上的所有解决方案似乎都无法解决。

–霍尔格·布兰德尔(Holger Brandl)
16年5月5日在18:50

@HolgerBrandl好点,我不知道该如何解决。这是我第一次听说set -e,所以我才学到了一些东西:)

–吕克
16年5月5日在19:51

$ SECONDS似乎不是一个好选择,因为它是一个内置变量,反映了启动Shell以来的时间。参见tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html

–霍尔格·布兰德尔(Holger Brandl)
16年5月10日在9:42

@HolgerBrandl很好,我不知道。 Kinda很高兴找到一个当前打开时间超过300万秒的终端:D。我更新了帖子。

–吕克
16年5月11日在7:40

酷技术!时间是| tr \\ n x |头-c $((1024 * 1024 * 1024 * 10))| grep n(使用10 GiB内存)需要1分46秒。在github.com/julman99/eatmemory运行julman99的eatmemory程序需要6秒钟。嗯,再加上下载和编译时间,但是在我的RHEL6.4机器上编译起来没有问题,而且很快。不过,我还是喜欢这种解决方案。为什么要重新发明轮子?

– Mike S
17-4-7在20:53



#4 楼

我建议运行内存有限的VM并测试软件,这比尝试在主机上填充内存的效率更高。

该方法还具有以下优势:这种情况会在其他地方导致OOM错误并挂起整个OS,您只能将正在测试的VM挂在机器上而不挂在其他可能正在运行的有用进程上。大量使用,您可以在具有各种低内存大小的一系列VM上同时运行测试实例。

#5 楼

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

只需通过dd或类似名称填充/ dev / shm。 />

评论


并非所有* nix都具有/ dev / shm。还有其他可移植的想法吗?

– Tadeusz A.Kadłubowski
13年8月8日在12:24

如果安装了pv,则有助于查看计数:dd if = / dev / zero bs = 1024 | pv -b -B 1024 | dd of = / dev / shm / fill bs = 1024

–奥修斯
17-09-26在20:01



如果需要速度,此方法是正确的选择!因为它可以在几秒钟内分配所需的RAM量。不要在/ dev / urandom上中继,它将占用100%的CPU,如果您的RAM很大,则需要几分钟。但是,/ dev / shm在现代的Ubuntu / Debian发行版中具有相对大小,其大小默认为物理RAM的50%。希望您可以重新挂载/ dev / shm或创建一个新的挂载点。只需确保它具有要分配的实际大小即可。

–develCuy
17年12月8日在19:25

自我注意:不要是> / dev / shm / asdf,因为它会使您的系统崩溃(即使启用了交换)

– phil294
20 Jul 25'0:21



#6 楼


运行linux;
mem=nn[KMG]内核引导参数引导

(有关详细信息,请查看linux / Documentation / kernel-parameters.txt)。

#7 楼

我保留了在点文件中执行类似操作的功能。 https://github.com/sagotsky/.dotfiles/blob/master/.functions#L248

function malloc() {
  if [[ $# -eq 0 ||  -eq '-h' ||  -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(/10)}')
    if [[ $N -gt  ]] ;then 
      N=
    fi
    sh -c "MEMBLOB=$(dd if=/dev/urandom bs=1MB count=$N) ; sleep 1"
  fi
}


评论


恕我直言,这是最好的解决方案,因为它基本上只需要dd即可工作,其他所有东西都可以在任何shell中解决。请注意,实际上,它至少暂时地占用了比数据dd产生的两倍的内存。在Debian 9上测试,破折号0.5.8-2.4。如果使用bash运行MEMBLOB部件,它将变得非常缓慢,并且使用dd生成量的四倍。

–P.Péter
18-10-16在7:46

#8 楼

一个简单的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)


评论


这可能很快就会被交换掉,对内存压力的实际影响很小(除非您也填满所有交换,通常需要一段时间)

– Joachim Sauer
13年8月8日在13:22

在有可用RAM的情况下,为什么要进行unix交换?实际上,这是在需要时驱逐磁盘缓存的一种可行方法。

–亚历山大·舒布利金(Alexander Shcheblikin)
13年8月8日在23:04

@AlexanderShcheblikin这个问题不是关于收回磁盘缓存的(这对性能测试很有用,但对低资源测试却没有作用)。

–吉尔斯'所以-不再是邪恶的'
13年9月9日在14:40

尽管我并没有试图强调自己的记忆力,但该解决方案在我的测试中努力弥补了一两个Gig。但是,@ JoachimSauer可以将sysctl vm.swappiness = 0设置为10,并将vm.min_free_kbytes设置为一个较小的值,也许为1024。 ...您确实应该能够使其变得相当慢,以至于导致计算机出现OOM状态。参见kernel.org/doc/Documentation/sysctl/vm.txt和kernel.org/doc/gorman/html/understand/understand005.html

– Mike S
17-4-4在20:03



只需一个1GB的衬板:python -c“ x =(1 * 1024 * 1024 * 1024/8)*(0,); raw_input()”

– adrianlzt
19-09-19在10:51

#9 楼

如果存在,ramfs呢?挂载并复制到大文件上?可能必须在具有大量内存的32位系统上一次运行几次。

#10 楼

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

评论


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

–干粉
13年8月8日在13:46

#11 楼

我认为这是一个错误的问题,理智被争夺最有创意的答案的人们淹没了。如果只需要模拟OOM条件,则无需填充内存。只需使用自定义分配器,并在分配一定数量后失败。这种方法对于SQLite似乎足够有效。

#12 楼

我为此编写了一个小型C ++程序:https://github.com/rmetzger/dynamic-ballooner

此实现的优点是定期检查是否需要释放或重新分配内存。

#13 楼


我需要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.

获取或复制或创建合理大小的文件;例如,创建一个1GB的文件,然后
cp my1gbfile /ramdisk/file001
cp my1gbfile /ramdisk/file002

# do 450 times; 450 GB of 512GB approx 90%

使用free -g观察分配了多少RAM。
注意:例如,具有512GB的物理内存,并且如果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


#14 楼

该程序非常适合分配固定的内存:

https://github.com/julman99/eatmemory