Я хочу провести небольшое тестирование ресурсов, и для этого мне нужно заполнить 90% свободной памяти.
Как я могу сделать это в *nix
системе?
Я хочу провести небольшое тестирование ресурсов, и для этого мне нужно заполнить 90% свободной памяти.
Как я могу сделать это в *nix
системе?
Ответы:
стресс-нг - это генератор рабочей нагрузки, который имитирует нагрузку cpu / mem / io / hdd в системах POSIX. Этот вызов должен сделать трюк в Linux <3.14:
stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Для Linux> = 3.14 вы можете MemAvailable
вместо этого использовать оценку доступной памяти для новых процессов без замены:
stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Адаптируйте /proc/meminfo
вызов с помощью free(1)
/ vm_stat(1)
/ etc. если вам нужно это портативный.
stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
--vm 1 and --vm-keep
очень важно. Просто --vm-bytes
ничего не делает, и вас могут ввести в заблуждение, что вы можете выделить столько памяти, сколько вам нужно / нужно. Я получил немного, пока я не попытался проверить себя, выделив 256 ГБ памяти. Это не недостаток в ответе, он предоставляет правильные флаги, просто дополнительную осторожность.
-m 1
. В соответствии со -m N
--vm N
N
malloc()/free()
Вы можете записать программу на C malloc()
в требуемую память, а затем использовать ее mlock()
для предотвращения замены памяти.
Затем просто дайте программе подождать ввода с клавиатуры, разблокируйте память, освободите память и выйдите.
calloc
столкнется с той же проблемой IIRC. Вся память будет просто указывать на одну и ту же страницу, доступную только для чтения. На самом деле он не будет выделен, пока вы не попытаетесь записать в него (что не будет работать, поскольку доступно только для чтения). Единственный способ быть действительно уверенным в том, что я знаю, это memset
использовать весь буфер. Для получения дополнительной информации см. Следующий ответ stackoverflow.com/a/2688522/713554
Я бы предложил запустить виртуальную машину с ограниченной памятью и протестировать программное обеспечение, которое было бы более эффективным, чем попытка заполнить память на хост-машине.
Этот метод также имеет то преимущество, что если ситуация с нехваткой памяти вызывает ошибки OOM в другом месте и приводит к зависанию всей ОС, вы вешаете только проверяемую виртуальную машину, а не свою машину, на которой могут выполняться другие полезные процессы.
Кроме того, если ваше тестирование не требует значительных ресурсов процессора или ввода-вывода, вы можете одновременно запускать экземпляры тестов на семействе виртуальных машин с различными объемами памяти.
Из этого комментария HN: https://news.ycombinator.com/item?id=6695581
Просто заполните / dev / shm через dd или аналогичный.
swapoff -a dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
pv
установлено, это помогает увидеть счет:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Если у вас есть основные инструменты GNU ( sh
, grep
, yes
и head
) , вы можете сделать это:
yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily
Это работает, потому что grep загружает всю строку данных в ОЗУ (я узнал об этом довольно неудачным образом, когда копировал образ диска). Линии, генерируется yes
, замещающие символами новой строки, будут бесконечно долго, но ограничены head
в $BYTES
байты, таким образом , Grep будет загружать $ Байт в памяти. Сам Grep использует как 100-200KB для меня, возможно, вам придется вычесть это для более точной суммы.
Если вы также хотите добавить ограничение по времени, это можно сделать довольно легко в bash
(не будет работать sh
):
cat <(yes | tr \\n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n
Эта <(command)
вещь, кажется, малоизвестна, но часто чрезвычайно полезна, больше информации об этом здесь: http://tldp.org/LDP/abs/html/process-sub.html
Затем для использования cat
: cat
будет ждать завершения ввода до выхода, а если оставить один из каналов открытым, он сохранит работу grep.
Если у вас есть pv
и вы хотите медленно увеличивать использование оперативной памяти:
yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n
Например:
yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n
Будет использовать до гигабайта со скоростью 1 МБ в секунду. В качестве дополнительного бонуса, pv
покажет вам текущий уровень использования и общее использование на данный момент. Конечно, это также может быть сделано с предыдущими вариантами:
yes | tr \\n x | head -c $BYTES | pv | grep n
Просто вставка | pv |
части покажет вам текущее состояние (пропускная способность и общее количество, по умолчанию, я думаю - в противном случае смотрите страницу man (ual)).
Почему другой ответ? В принятом ответе рекомендуется установить пакет (держу пари, что для каждого набора микросхем есть релиз, не требующий менеджера пакетов); В ответе, получившем наибольшее количество голосов, рекомендуется компилировать программу на Си (у меня не было компилятора или набора инструментов для компиляции для вашей целевой платформы); во втором ответе с наибольшим количеством голосов рекомендуется запустить приложение на виртуальной машине (да, я просто добавлю внутреннюю SD-карту этого телефона через USB или что-то еще и создаю образ виртуальной коробки); третий предлагает модифицировать что-то в последовательности загрузки, которая не заполняет RAM должным образом; четвертый работает только в том случае, если точка монтирования / dev / shm (1) существует и (2) велика (для перемонтирования требуется root); пятый сочетает в себе многие из вышеперечисленных без примера кода; шестой - отличный ответ, но я не видел его до того, как придумал свой собственный подход, поэтому я решил добавить свою собственную, в том числе и потому, что ее короче запомнить или напечатать, если вы не видите, что линия мембраны - это суть дела; седьмой снова не отвечает на вопрос (вместо него используется ulimit для ограничения процесса); восьмой пытается заставить вас установить python; Девятый думает, что мы все очень не творческие, и, наконец, десятый написал свою собственную программу на C ++, которая вызывает ту же проблему, что и ответ с наибольшим количеством голосов.
set -e
, поэтому я только что-то узнал :)
time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n
(использовать память 10 ГиБ) занимает 1 минуту 46 секунд. Запуск программы еды на julman99 по адресу github.com/julman99/eatmemory занимает 6 секунд. ... Ну, плюс время загрузки и компиляции, но оно скомпилировано без проблем ... и очень быстро ... на моей машине RHEL6.4. Тем не менее, мне нравится это решение. Зачем изобретать велосипед?
У меня есть функция для создания чего-то похожего в моих точечных файлах. 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
}
Как найти простое решение на 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)
sysctl vm.swappiness=0
и, кроме того, установить vm.min_free_kbytes на небольшое число, возможно, 1024. Я не пробовал, но в документах говорится, что именно так вы контролируете скорость замены ... вы должны в состоянии сделать это довольно медленно, вплоть до возникновения состояния OOM на вашей машине. См. Kernel.org/doc/Documentation/sysctl/vm.txt и kernel.org/doc/gorman/html/understand/understand005.html
Как насчет ramfs, если он существует? Смонтировать и скопировать большой файл? Если нет /dev/shm
и нет ramfs - я думаю, крошечная C-программа, которая делает большой malloc на основе некоторого входного значения? Возможно, придется запускать его несколько раз одновременно на 32-битной системе с большим объемом памяти.
Если вы хотите протестировать определенный процесс с ограниченной памятью, вам лучше использовать ulimit
ограниченный объем выделяемой памяти.
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.
Я думаю, что это тот случай, когда задают неправильный вопрос, и люди, борющиеся за самый креативный ответ, заглушают здравомыслие. Если вам нужно только имитировать условия ООМ, вам не нужно заполнять память. Просто используйте пользовательский распределитель, и он завершится ошибкой после определенного количества распределений. Этот подход, кажется, работает достаточно хорошо для SQLite .
Я написал эту маленькую C ++ программу для этого: https://github.com/rmetzger/dynamic-ballooner
Преимущество этой реализации заключается в том, что она периодически проверяет, нужно ли освободить или перераспределить память.