Ich möchte einige ressourcenschonende Tests durchführen und dafür muss der freie Speicher zu 90% voll sein.
Wie kann ich das auf einem *nix
System machen?
Ich möchte einige ressourcenschonende Tests durchführen und dafür muss der freie Speicher zu 90% voll sein.
Wie kann ich das auf einem *nix
System machen?
Antworten:
stress-ng ist ein Workload-Generator, der die Belastung von POSIX-Systemen durch CPU / Mem / IO / HDD simuliert. Dieser Aufruf sollte unter Linux <3.14 funktionieren:
stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Unter Linux> = 3.14 können Sie MemAvailable
stattdessen den verfügbaren Arbeitsspeicher für neue Prozesse schätzen, ohne den Arbeitsspeicher auszutauschen:
stress-ng --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
Passen Sie den /proc/meminfo
Aufruf mit free(1)
/ vm_stat(1)
/ etc an. wenn Sie es tragbar brauchen.
stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.98;}' < /proc/meminfo)k --vm-keep -m 1
--vm 1 and --vm-keep
sind sehr wichtig. Wenn --vm-bytes
Sie einfach nichts tun, werden Sie möglicherweise in die Irre geführt und denken, Sie können so viel Speicher zuweisen, wie Sie benötigen / möchten. Ich habe ein bisschen davon mitbekommen, bis ich versucht habe, mich durch Zuweisen von 256 GB Speicher auf meine Gesundheit zu überprüfen. Dies ist kein Fehler in der Antwort, sondern liefert die korrekten Flags, nur eine zusätzliche Warnung.
-m 1
. Laut der Manpage zu Stress -m N
ist die --vm N
N
malloc()/free()
Sie können ein C-Programm in malloc()
den erforderlichen Speicher schreiben und dann verwenden mlock()
, um zu verhindern, dass der Speicher ausgelagert wird.
Lassen Sie das Programm einfach auf die Tastatureingabe warten und entsperren Sie den Speicher. Geben Sie den Speicher frei und beenden Sie das Programm.
calloc
wird auf das gleiche Problem IIRC laufen. Der gesamte Speicher zeigt nur auf dieselbe schreibgeschützte Seite mit Nullen. Es wird erst zugewiesen, wenn Sie versuchen, darauf zu schreiben (was nicht funktioniert, da es schreibgeschützt ist). Der einzige Weg, um wirklich sicher zu sein, dass ich es weiß, ist, einen memset
Teil des gesamten Puffers zu machen. Weitere Informationen finden
Ich würde vorschlagen, eine VM mit begrenztem Speicher auszuführen und die Software darin zu testen, was ein effizienterer Test wäre als der Versuch, den Speicher auf dem Hostcomputer zu füllen.
Diese Methode hat auch den Vorteil, dass Sie nur die zu testende VM hängen und nicht die Maschine, auf der möglicherweise andere nützliche Prozesse ausgeführt werden, wenn die Situation mit wenig Arbeitsspeicher an anderer Stelle OOM-Fehler verursacht und das gesamte Betriebssystem blockiert.
Auch wenn Ihre Tests nicht CPU- oder E / A-intensiv sind, können Sie Instanzen der Tests gleichzeitig auf einer Familie von VMs mit einer Vielzahl von geringen Speichergrößen ausführen.
Aus diesem HN-Kommentar: https://news.ycombinator.com/item?id=6695581
Füllen Sie einfach / dev / shm über dd oder ähnliches.
swapoff -a dd if=/dev/zero of=/dev/shm/fill bs=1k count=1024k
pv
installiert ist, hilft es, die Anzahl zu sehen:dd if=/dev/zero bs=1024 |pv -b -B 1024 | dd of=/dev/shm/fill bs=1024
Wenn Sie grundlegenden GNU - Tools haben ( sh
, grep
, yes
und head
) Sie können dies tun:
yes | tr \\n x | head -c $BYTES | grep n
# Protip: use `head -c $((1024*1024*2))` to calculate 2MB easily
Dies funktioniert, weil grep die gesamte Datenzeile in den Arbeitsspeicher lädt (ich habe dies auf eine ziemlich unglückliche Weise erfahren, als ich ein Disk-Image gegriffen habe). Die Zeile, die durch das yes
Ersetzen von Zeilenumbrüchen generiert wird, ist unendlich lang, aber head
auf $BYTES
Bytes begrenzt, sodass grep $ BYTES in den Speicher lädt. Grep selbst verwendet für mich etwa 100-200 KB. Möglicherweise müssen Sie dies subtrahieren, um einen genaueren Betrag zu erhalten.
Wenn Sie auch eine Zeitbeschränkung hinzufügen möchten, können Sie dies ganz einfach in ausführen bash
(funktioniert nicht in sh
):
cat <(yes | tr \\n x | head -c $BYTES) <(sleep $NumberOfSeconds) | grep n
Das <(command)
Ding scheint wenig bekannt zu sein, ist aber oft sehr nützlich. Weitere Informationen dazu finden Sie hier: http://tldp.org/LDP/abs/html/process-sub.html
Dann gilt für die Verwendung von cat
: cat
für Eingaben abgeschlossen warten , bis Verlassen und durch eines der Rohre offen zu halten, wird es grep am Leben zu halten.
Wenn Sie den pv
RAM-Verbrauch langsam erhöhen möchten und müssen :
yes | tr \\n x | head -c $BYTES | pv -L $BYTESPERSEC | grep n
Zum Beispiel:
yes | tr \\n x | head -c $((1024*1024*1024)) | pv -L $((1024*1024)) | grep n
Verbraucht bis zu einem Gigabyte bei einer Rate von 1 MB pro Sekunde. Als zusätzlichen Bonus pv
werden Ihnen die aktuelle Nutzungsrate und die bisherige Gesamtnutzung angezeigt. Dies kann natürlich auch mit vorherigen Varianten durchgeführt werden:
yes | tr \\n x | head -c $BYTES | pv | grep n
Durch einfaches Einfügen des | pv |
Teils wird der aktuelle Status angezeigt (Durchsatz und Gesamtmenge, denke ich, standardmäßig - ansonsten wird die Man-Seite (ual) angezeigt).
Warum noch eine Antwort? In der akzeptierten Antwort wird empfohlen, ein Paket zu installieren (ich wette, es gibt eine Version für jeden Chipsatz, für die kein Paketmanager erforderlich ist). In der Antwort mit der höchsten Bewertung wird empfohlen, ein C-Programm zu kompilieren (für die Kompilierung für Ihre Zielplattform war weder ein Compiler noch eine Toolchain installiert). Die zweithäufigste Antwort empfiehlt, die Anwendung in einer virtuellen Maschine auszuführen (ja, lassen Sie mich einfach die interne SD-Karte dieses Telefons über USB oder so etwas austauschen und ein Virtualbox-Image erstellen). der dritte schlägt vor, etwas in der Startsequenz zu ändern, das den RAM nicht wie gewünscht füllt; Der vierte funktioniert nur, sofern der / dev / shm-Mountpoint (1) existiert und (2) groß ist (Remounting benötigt root). der fünfte kombiniert viele der oben genannten ohne Beispielcode; Die sechste ist eine großartige Antwort, aber ich habe diese Antwort nicht gesehen, bevor ich meinen eigenen Ansatz gefunden habe. Also dachte ich, ich würde mein eigenes hinzufügen, auch weil es kürzer ist, sich zu erinnern oder umzuschreiben, wenn man nicht sieht, dass die Memblob-Linie tatsächlich der springende Punkt ist. das siebte beantwortet die Frage nicht (verwendet stattdessen ulimit, um einen Prozess einzuschränken); Der achte versucht, Sie dazu zu bringen, Python zu installieren. Die neunte hält uns alle für sehr unkreativ, und schließlich hat die zehnte ihr eigenes C ++ - Programm geschrieben, das das gleiche Problem verursacht wie die Antwort, für die die meisten Stimmen abgegeben haben.
set -e
, also habe ich gerade etwas gelernt :)
time yes | tr \\n x | head -c $((1024*1024*1024*10)) | grep n
(benutze 10 GiB Speicher) dauert 1 Minute 46 Sekunden. Das Ausführen des Programms eatmemory von julman99 unter github.com/julman99/eatmemory dauert 6 Sekunden. ... Nun, plus der Download- und Kompilierungszeit, aber ohne Probleme kompiliert ... und sehr schnell ... auf meinem RHEL6.4-Rechner. Trotzdem mag ich diese Lösung. Warum das Rad neu erfinden?
Ich behalte eine Funktion, um etwas Ähnliches in meinen Punktedateien zu tun. 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
}
Wie viel kostet eine einfache Python-Lösung?
#!/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
und außerdem auf eine kleine Zahl setzen, vielleicht 1024. Ich habe es nicht ausprobiert, aber die Dokumentation sagt, dass Sie auf diese Weise die Schnelligkeit des Austauschs steuern ... Sie sollten es sein in der Lage, es in der Tat ziemlich langsam zu machen, bis ein OOM-Zustand auf Ihrem Computer verursacht wird. Siehe kernel.org/doc/Documentation/sysctl/vm.txt und kernel.org/doc/gorman/html/understand/understand005.html
Wie wäre es mit Ramfs, wenn es existiert? Hängen Sie es ein und kopieren Sie über eine große Datei? Wenn es keine /dev/shm
und keine RAMFS gibt - ich denke, ein kleines C-Programm, das einen großen Malloc basierend auf einem Eingabewert ausführt? Möglicherweise muss es auf einem 32-Bit-System mit viel Speicher mehrere Male gleichzeitig ausgeführt werden.
Wenn Sie einen bestimmten Prozess mit begrenztem Speicher testen möchten, ist es möglicherweise besser ulimit
, die Menge des zuweisbaren Speichers zu beschränken.
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.
Ich denke, dies ist ein Fall, in dem die falsche Frage gestellt wird und die Vernunft von Leuten übertönt wird, die um die kreativste Antwort konkurrieren. Wenn Sie nur OOM-Bedingungen simulieren müssen, müssen Sie den Speicher nicht füllen. Verwenden Sie einfach einen benutzerdefinierten Allokator und lassen Sie ihn nach einer bestimmten Anzahl von Allokationen fehlschlagen. Dieser Ansatz scheint für SQLite gut genug zu funktionieren .
Ich habe dieses kleine C ++ - Programm dafür geschrieben: https://github.com/rmetzger/dynamic-ballooner
Der Vorteil dieser Implementierung besteht darin, dass regelmäßig überprüft wird, ob Speicher freigegeben oder neu zugewiesen werden muss.