Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to do some low-resources testing and for that I need to have 90% of the free memory full.

How can I do this on a *nix system?

share|improve this question
3  
Does it really have to work on any *nix system? – Michael Kjörling Nov 8 '13 at 12:31
29  
Instead of jut filling memory, could you instead create a VM (using docker, or vagrant, or something similar) that has a limited amount of memory? – abendigo Nov 8 '13 at 13:27
3  
@abendigo For a QA many of the solutions presented here are useful: for a general purpose OS without a specific platform the VM or kernel boot parameters could be useful, but for a embedded system where you know the memory specification of the targeted system I would go for the filling of the free memory. – Eduard Florinescu Nov 9 '13 at 17:40
    
In case anyone else is a little shocked by the scoring here: meta.unix.stackexchange.com/questions/1513/…? – goldilocks Nov 13 '13 at 14:46
    
See also: unix.stackexchange.com/a/1368/52956 – Wilf Jun 18 '15 at 18:42

12 Answers 12

up vote 78 down vote accepted

stress is a workload generator that simulates cpu/mem/io/hdd stress on POSIX systems. This call should do the trick on Linux:

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

Adapt the /proc/meminfo call with free(1)/vm_stat(1)/etc. if you need it portable.

share|improve this answer
1  
stress --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.097;}' < /proc/meminfo)k --vm-keep -m 10 – Robert Oct 23 '15 at 16:47

You can write a C program to malloc() the required memory and then use mlock() to prevent the memory from being swapped out.

Then just let the program wait for keyboard input, and unlock the memory, free the memory and exit.

share|improve this answer
23  
Long time back I had to test similar use case. I observed that until you write something to that memory it will not be actually allocated(i.e. until page fault happens) . I am not sure whether mlock() take cares of that. – siri Nov 8 '13 at 13:31
2  
I concur with @siri; however, it depends on which variant UNIX you are using. – Anthony Nov 8 '13 at 13:34
1  
Some inspiration for the code. Furthermore, I think you don't need to unlock/free the memory. The OS is going to do that for you when your process has ended. – Sebastian Nov 8 '13 at 13:44
7  
You probably have to actually write to the memory, the kernel might just overcommit if you only malloc it. If configured to, e.g. Linux will let malloc return successfully without actually having the memory free, and only actually allocate the memory when it is being written to. See win.tue.nl/~aeb/linux/lk/lk-9.html – Bjarke Freund-Hansen Nov 8 '13 at 14:32
5  
@Sebastian: calloc will run into the same problem IIRC. All the memory will just point to the same read-only zeroed page. It won't actually get allocated until you try to write to it (which won't work since it is read-only). The only way of being really sure that I know is to do a memset of the whole buffer. See the following answer for more info stackoverflow.com/a/2688522/713554 – Leo Nov 8 '13 at 16:43

I would suggest running a VM with limited memory and testing the software in that would be a more efficient test than trying to fill memory on the host machine.

That method also has the advantage that if the low memory situation causes OOM errors elsewhere and hangs the whole OS, you only hang the VM you are testing in not your machine that you might have other useful processes running on.

Also if your testing is not CPU or IO intensive, you could concurrently run instances of the tests on a family of VMs with a variety of low memory sizes.

share|improve this answer
  1. run linux;
  2. boot with mem=nn[KMG] kernel boot parameter

(look in linux/Documentation/kernel-parameters.txt for details).

share|improve this answer

From this HN comment: https://news.ycombinator.com/item?id=6695581

Just fill /dev/shm via dd or similar.

swapoff -a
dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
share|improve this answer
7  
Not all *nixes have /dev/shm. Any more portable idea? – Tadeusz A. Kadłubowski Nov 8 '13 at 12:24

How about ramfs if it exists? Mount it and copy over a large file? If there's no /dev/shm and no ramfs - I guess a tiny C program that does a large malloc based on some input value? Might have to run it a few times at once on a 32 bit system with a lot of memory.

share|improve this answer

I keep a function to do something similar in my 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
}
share|improve this answer

If you want to test a particular process with limited memory you might be better off using ulimit to restrict the amount of allocatable memory.

share|improve this answer
1  
Actually this does not work on linux (dunno about other *nixes). man setrlimit: 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. – Patrick Nov 8 '13 at 13:46

How abount a simple python solution?

#!/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)
share|improve this answer
7  
That will probably quickly be swapped out, having very little actual impact on memory pressure (unless you fill up all the swap as well, which will take a while, usually) – Joachim Sauer Nov 8 '13 at 13:22
    
Why would a unix swap while there is available RAM? This is actually a plausible way to evict disk cache when need be. – Alexander Shcheblikin Nov 8 '13 at 23:04
    
@AlexanderShcheblikin This question isn't about evicting disk cache (which is useful for performance testing but not for low resources testing). – Gilles Nov 9 '13 at 14:40

I think this is a case of asking the wrong question and sanity being drowned out by people competing for the most creative answer. If you only need to simulate OOM conditions, you don't need to fill memory. Just use a custom allocator and have it fail after a certain number of allocations. This approach seems to work well enough for SQLite.

share|improve this answer

I wrote this little C++ program for that: https://github.com/rmetzger/dynamic-ballooner

The advantage of this implementation is that is periodically checks if it needs to free or re-allocate memory.

share|improve this answer

If you have basic GNU tools (sh, grep, yes and head) you can do this:

yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily

This works because grep loads the entire line of data in RAM (I learned this in a rather unfortunate way when grepping a disk image). The line, generated by yes, replacing newlines, will be infinitely long, but is limited by head to $BYTES bytes, thus grep will load $BYTES in memory. Grep itself uses like 100-200KB for me, you might need to subtract that for a more precise amount.

If you want to also add a time constraint, this can be done quite easily in bash (will not work in sh):

cat <(yes | tr \\n x | head -c $BYTES) <(sleep $SECONDS) | grep n

The <(command) thing seems to be little known but is often extremely useful, more info on it here: http://tldp.org/LDP/abs/html/process-sub.html

Then for the use of cat: cat will wait for inputs to complete until exiting, and by keeping one of the pipes open, it will keep grep alive.

If you have pv and want to slowly increase RAM use:

yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n

For example:

yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n

Will use up to a gigabyte at a rate of 1MB per second. As an added bonus, pv will show you the current rate of use and the total use so far. Of course this can also be done with previous variants:

yes | tr \\n x | head -c $BYTES | pv | grep n

Just inserting the | pv | part will show you the current status (throughput and total, by default, I think - otherwise see the man(ual) page).


Why another answer? The accepted answer recommends installing a package (I bet there's a release for every chipset without needing a package manager); the top voted answer recommends compiling a C program (I did not have a compiler or toolchain installed to compile for your target platform); the second top voted answer recommends running the application in a VM (yeah let me just dd this phone's internal sdcard over usb or something and create a virtualbox image); the third suggests modifying something in the boot sequence which does not fill the RAM as desired; the fourth only works in so far as the /dev/shm mountpoint (1) exists and (2) is large (remounting needs root); the fifth combines many of the above without sample code; the sixth is a great answer but I did not see this answer before coming up with my own approach, so I thought I'd add my own, also because it's shorter to remember or type over if you don't see that the memblob line is actually the crux of the matter; the seventh again does not answer the question (uses ulimit to limit a process instead); the eighth tries to get you to install python; the ninth thinks we're all very uncreative and finally the tenth wrote his own C++ program which causes the same issue as the top voted answer.

share|improve this answer

protected by Gilles Nov 9 '13 at 14:37

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.