Я хочу зробити тестування з низькими ресурсами, і для цього мені потрібно заповнити 90% вільної пам'яті.
Як я можу це зробити в *nix
системі?
Я хочу зробити тестування з низькими ресурсами, і для цього мені потрібно заповнити 90% вільної пам'яті.
Як я можу це зробити в *nix
системі?
Відповіді:
stress-ng - це генератор робочого навантаження, який імітує напругу процесора / 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)
/ тощо. якщо вам це потрібно портативні.
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
Я б запропонував запустити VM з обмеженою пам’яттю та протестувати програмне забезпечення, що було б більш ефективним тестом, ніж спроба заповнити пам'ять на хост-машині.
Цей метод також має перевагу в тому, що якщо ситуація з низькою пам'яттю спричиняє помилки OOM в іншому місці і вішає всю ОС, ви вішаєте лише те, що ви тестуєте, на машину, яку ви не перевіряєте, на вашу машину.
Крім того, якщо тестування не є процесорним або IO інтенсивним, ви можете одночасно запускати екземпляри тестів на сімействі VM з різними низькими розмірами пам'яті.
З цього коментаря до НН: 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
буде чекати, коли входи завершаться до виходу, і, тримаючи одну з труб відкритою, вона збереже жир.
Якщо у вас є 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)).
Чому інша відповідь? Прийнята відповідь рекомендує встановити пакет (я вважаю, що є випуск для кожного чіпсета, не потребуючи менеджера пакунків); відповідь, що голосує вгорі, рекомендує скласти програму C (у мене не було встановлено компілятор чи інструментальну ланцюжок для компіляції для вашої цільової платформи); друга відповідь, проголосована вгорі, рекомендує запустити додаток у віртуальній машині (так, дозвольте мені просто занести внутрішню sdcard цього телефону через usb чи щось подібне та створити образ virtualbox); третій пропонує змінити щось у послідовності завантаження, що не заповнює оперативну пам'ять за бажанням; четвертий працює лише в тому випадку, коли існує точка встановлення / dev / shm (1) і (2) велика (перепланування потребує кореня); п’яте поєднує багато вищезазначеного без зразкового коду; шостий - чудова відповідь, але я не бачив цієї відповіді, перш ніж придумати власний підхід, тому я подумав, що я додаю своє, також тому, що це коротше запам’ятовувати або надрукувати, якщо ви не бачите, що лінія мембрани - це насправді суть справи; сьомий знову не відповідає на питання (використовує ulimit для обмеження процесу замість цього); восьма намагається змусити вас встановити python; дев'ятий вважає, що ми всі дуже нетворчі, і, нарешті, десятий написав свою власну програму C ++, яка викликає ту саму проблему, що і відповідь, яка проголосувала вгорі.
set -e
, тому я просто щось дізнався :)
time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n
(використовуйте 10 Гб пам'яті) займає 1 хвилину 46 секунд. Запуск програми jumman99 на їжу на сайті 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
}
Як обходиться простим рішенням пітона?
#!/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.
Я думаю, що це випадок задати неправильне запитання і заглушити людей, які змагаються за найкреативнішу відповідь. Якщо вам потрібно лише моделювати умови OOM, вам не потрібно заповнювати пам'ять. Просто використовуйте спеціальний розподільник, і він не вийде після певної кількості виділень. Цей підхід, здається, працює досить добре для SQLite .
Я написав для цього маленьку програму C ++: https://github.com/rmetzger/dynamic-ballooner
Перевага цієї реалізації полягає в тому, що періодично перевіряється, чи потрібно звільнити або перерозподілити пам'ять.