Chcę przeprowadzić testowanie przy niskim zużyciu zasobów i do tego muszę mieć 90% wolnej pamięci.
Jak mogę to zrobić w *nix
systemie?
Chcę przeprowadzić testowanie przy niskim zużyciu zasobów i do tego muszę mieć 90% wolnej pamięci.
Jak mogę to zrobić w *nix
systemie?
Odpowiedzi:
stress-ng to generator obciążenia, który symuluje obciążenie procesora / mem / io / hdd w systemach POSIX. To wywołanie powinno załatwić sprawę w Linuksie <3.14:
stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
W przypadku systemu Linux> = 3.14 MemAvailable
zamiast tego można użyć do oszacowania dostępnej pamięci dla nowych procesów bez zamiany:
stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Dostosuj /proc/meminfo
połączenie za pomocą free(1)
/ vm_stat(1)
/ etc. jeśli potrzebujesz go przenośnego.
stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
--vm 1 and --vm-keep
są bardzo ważne. Po prostu --vm-bytes
nic nie robi i możesz zostać wprowadzony w błąd, że możesz przydzielić tyle pamięci, ile potrzebujesz / chcesz. Uderzyło mnie to, dopóki nie spróbowałem sprawdzić zdrowia psychicznego, przydzielając 256G pamięci. To nie jest wada w odpowiedzi, zapewnia prawidłowe flagi, a jedynie dodatkową ostrożność.
-m 1
. Według strony stresu, -m N
jest skrót od --vm N
: spawn N
pracowników spinning onmalloc()/free()
Możesz napisać program C do malloc()
wymaganej pamięci, a następnie użyć, mlock()
aby zapobiec zamianie pamięci.
Następnie pozwól programowi czekać na wprowadzenie danych z klawiatury i odblokuj pamięć, zwolnij pamięć i wyjdź.
calloc
ten sam problem IIRC. Cała pamięć będzie po prostu wskazywać tę samą stronę zerowaną tylko do odczytu. W rzeczywistości nie zostanie przydzielony, dopóki nie spróbujesz do niego napisać (co nie będzie działać, ponieważ jest tylko do odczytu). Jedynym sposobem, aby być naprawdę pewnym, że wiem, jest zrobienie memset
całego bufora. Aby uzyskać więcej informacji, zobacz następującą odpowiedź stackoverflow.com/a/2688522/713554
Sugerowałbym uruchomienie maszyny wirtualnej z ograniczoną pamięcią i przetestowanie oprogramowania, co byłoby bardziej wydajnym testem niż próba zapełnienia pamięci na komputerze hosta.
Ta metoda ma również tę zaletę, że jeśli sytuacja braku pamięci powoduje błędy OOM w innym miejscu i zawiesza cały system operacyjny, zawieszasz tylko testowaną maszynę wirtualną, a nie maszynę, na której mogą działać inne przydatne procesy.
Ponadto, jeśli testowanie nie wymaga użycia procesora ani operacji we / wy, można jednocześnie uruchamiać instancje testów na rodzinie maszyn wirtualnych o różnych małych rozmiarach pamięci.
Z tego komentarza HN: https://news.ycombinator.com/item?id=6695581
Wystarczy wypełnić / dev / shm przez dd lub podobny.
swapoff -a dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
pv
jest zainstalowany, pomaga zobaczyć liczbę:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Jeśli masz podstawowe narzędzia GNU ( sh
, grep
, yes
i head
) można to zrobić:
yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily
Działa to, ponieważ grep ładuje całą linię danych do pamięci RAM (nauczyłem się tego w dość niefortunny sposób podczas grepowania obrazu dysku). Linia, generowane przez yes
zastąpienie nowymi liniami, będzie nieskończenie długo, ale jest ograniczona head
do $BYTES
bajtów, co grep załaduje $ bajtów pamięci. Sam Grep używa dla mnie 100-200 KB, być może będziesz musiał go odjąć, aby uzyskać dokładniejszą kwotę.
Jeśli chcesz również dodać ograniczenie czasowe, możesz to zrobić dość łatwo w bash
(nie będzie działać sh
):
cat <(yes | tr \\n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n
Sprawa <(command)
wydaje się mało znana, ale często bardzo przydatna, więcej informacji na ten temat można znaleźć tutaj: http://tldp.org/LDP/abs/html/process-sub.html
Następnie użycie cat
: cat
zaczeka na zakończenie wprowadzania danych aż do wyjścia, a utrzymywanie jednej z rur otwartych utrzyma grep przy życiu.
Jeśli masz pv
i chcesz powoli zwiększać ilość pamięci RAM, użyj:
yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n
Na przykład:
yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n
Zużywa do gigabajta z prędkością 1 MB na sekundę. Jako dodatkowy bonus pv
pokaże ci aktualny poziom użytkowania i całkowite wykorzystanie do tej pory. Oczywiście można to również zrobić w przypadku poprzednich wariantów:
yes | tr \\n x | head -c $BYTES | pv | grep n
Po prostu wstawienie | pv |
części pokaże ci aktualny status (domyślnie przepustowość i całkowity, domyślnie - inaczej zobacz stronę man (ual)).
Dlaczego kolejna odpowiedź? Zaakceptowana odpowiedź zaleca zainstalowanie pakietu (założę się, że dla każdego mikroukładu dostępna jest wersja bez menedżera pakietów); najczęściej głosowana odpowiedź zaleca kompilację programu w języku C (nie miałem zainstalowanego kompilatora ani zestawu narzędzi do kompilacji dla platformy docelowej); druga najczęściej głosowana odpowiedź zaleca uruchomienie aplikacji na maszynie wirtualnej (tak, pozwól mi po prostu dodać wewnętrzną kartę SD tego telefonu nad USB lub coś takiego i stworzyć obraz Virtualbox); trzeci sugeruje modyfikację czegoś w sekwencji rozruchowej, która nie wypełnia pamięci RAM zgodnie z potrzebami; czwarty działa tylko w takim stopniu, w jakim istnieje punkt montowania / dev / shm (1), a (2) jest duży (ponowne podłączanie wymaga roota); piąty łączy wiele powyższych bez przykładowego kodu; szósta to świetna odpowiedź, ale nie widziałem tej odpowiedzi, zanim wpadłem na własne podejście, więc pomyślałem, że dodam własne, także dlatego, że krótsze jest zapamiętywanie lub pisanie, jeśli nie widzisz, że linia memblob jest sednem sprawy; siódmy ponownie nie odpowiada na pytanie (zamiast tego używa ulimit, aby ograniczyć proces); ósma próbuje zmusić cię do zainstalowania Pythona; dziewiąta uważa, że wszyscy jesteśmy bardzo mało kreatywni, a wreszcie dziesiąta napisała swój własny program C ++, który powoduje ten sam problem, co najczęściej głosowana odpowiedź.
set -e
, więc właśnie się czegoś nauczyłem :)
time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n
(użyj pamięci 10 GiB) zajmuje 1 minutę 46 sekund. Uruchomienie programu eatmemory julman99 na github.com/julman99/eatmemory zajmuje 6 sekund. ... Cóż, plus czas pobierania i kompilacji, ale skompilowałem bez problemu ... i bardzo szybko ... na moim komputerze RHEL6.4. Mimo to podoba mi się to rozwiązanie. Po co wymyślać koło ponownie?
Utrzymuję funkcję robienia czegoś podobnego w moich plikach dot. 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
}
Jak obliczyć proste rozwiązanie 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
a ponadto ustawić vm.min_free_kbytes na małą liczbę, może 1024. Nie próbowałem tego, ale doktorzy mówią, że w ten sposób kontrolujesz szybkość zamiany ... powinieneś być jest w stanie spowolnić go do tego stopnia, że powoduje stan OOM na twoim komputerze. Zobacz kernel.org/doc/Documentation/sysctl/vm.txt i kernel.org/doc/gorman/html/understand/understand005.html
Jeśli chcesz przetestować konkretny proces z ograniczoną pamięcią, lepiej użyć ulimit
ograniczania ilości przydzielanej pamięci.
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.
Myślę, że jest to przypadek zadawania niewłaściwego pytania i zdrowego rozsądku zagłuszanego przez ludzi rywalizujących o najbardziej kreatywną odpowiedź. Jeśli potrzebujesz tylko zasymulować warunki OOM, nie musisz wypełniać pamięci. Wystarczy użyć niestandardowego programu przydzielającego i spowodować jego awarię po określonej liczbie alokacji. To podejście wydaje się działać wystarczająco dobrze dla SQLite .
Napisałem do tego mały program C ++: https://github.com/rmetzger/dynamic-ballooner
Zaletą tej implementacji jest to, że okresowo sprawdza, czy trzeba zwolnić lub ponownie przydzielić pamięć.