Verhindern, dass das System einfriert oder nicht mehr reagiert, weil der Arbeitsspeicher ausgelagert wird

48

Wenn ein Prozess viel Speicher benötigt, verschiebt das System alle anderen Prozesse in die Auslagerungsdatei. Dazu gehören scheinbar notwendige Prozesse wie der X11-Server oder das Terminal.

Wenn also ein Prozess unbegrenzt zugeteilt wird, reagiert alles nicht mehr, bis dieser Prozess vom OOM-Killer beendet wird. Mein Laptop scheint besonders vernünftig zu sein und reagiert extrem schlecht. Ich habe gerade eine GANZE STUNDE auf die Beendigung des Prozesses gewartet, in der nicht einmal der Mauszeiger bewegt werden konnte.

Wie kann dies vermieden werden?

1) Deaktiviere den Swap => Ich starte oft viele Prozesse, die dann inaktiv werden. Die inaktiven sollten in den Swap verschoben werden.

2) Holen Sie sich eine SSD => zu teuer

3) setze ein maximales Speicherlimit => aber dann scheitert es, wenn ein Programm eine vernünftige, große Menge an Speicher benötigt. Das Problem ist nicht, dass es zu viel verbraucht, sondern dass es die anderen Prozesse unterdrückt

4) wichtige Programme (X11, bash, kill, top, ...) im Speicher behalten und niemals vertauschen => geht das? Wie? vielleicht nur große programme tauschen?

5)?

BeniBela
quelle
Und es passierte wieder :( Gcc gestartet, während Firefox lief, war alles für eine halbe Stunde blockiert. Keine Mausbewegung, kein E-Book-Lesen
BeniBela
Ich bin nicht sicher, ob ich verstehe, was Sie wollen. Möchten Sie, dass das System die Dinge mit den vorhandenen Ressourcen auf magische Weise schneller erledigt? Möchten Sie, dass Prozesse, die viel Speicher benötigen, früher beendet werden?
David Schwartz
Klingt so, als ob Sie wirklich mehr RAM brauchen. Oder weniger "inaktive" Hintergrundaufgaben.
Daniel B
2
Sie können die Tastenkombination Alt + SysRq + F verwenden , um die Ausführung des OOM-Killers zu erzwingen. Dies kann die unnötige Zeit verkürzen, die erforderlich ist, um darauf zu warten, dass Ihr System eine Konsole öffnet, damit Sie einen Prozess beenden können.
Hololeap
Korrigieren Sie mich, wenn ich falsch liege, aber dieses Problem tatsächlich so klingt, als ob das System nach Speicherplatz sucht, der vorhanden sein sollte, aber nicht vorhanden ist (Swap-Partition ist zu klein). Nicht genügend Auslagerungsspeicher führt dazu, dass das System die Festplatte (oder SSD) nach verfügbarem Speicherplatz durchsucht.
18.

Antworten:

45

TL; DR

Kurz vorübergehend / Antwort

  • Am einfachsten : Verwenden Sie eine kleinere Swap-Partition, und vermeiden Sie, dass der Kernel versucht, der Lüge gerecht zu werden, dass es keine Speicherbeschränkung gibt, indem Sie Prozesse aus langsamen Speichern ausführen.
    • Bei einem großen Tausch wird der OOM (Out-of-Memory-Manager) nicht früh genug ausgeführt. Normalerweise hängt es vom virtuellen Speicher ab und hat meiner Erfahrung nach die Dinge nicht getötet, bis der gesamte Swap voll war, daher das Thrashing- und Crawling-System ...
  • Brauchen Sie einen großen Swap für den Winterschlaf?
    • Versucht / problematisch : Stellen Sie einige Grenzwerte ein (z. B. überprüfen Sie ulimit -v, und setzen Sie möglicherweise ein hartes oder weiches Limit mithilfe der asOption in limits.conf). Früher hat dies gut funktioniert, aber dank der Einführung von WebKit gigacageerwarten viele Gnome-Apps jetzt unbegrenzte Adressräume und können nicht ausgeführt werden!
    • Versuchte / problematisch : Die overcommit Politik und das Verhältnis eine andere Art und Weise zu verwalten , zu versuchen und zu mildern diese (zB sysctl vm.overcommit_memory, sysctl vm.overcommit_ratioaber dieser Ansatz nicht für mich funktioniert.
    • Schwierig / kompliziert : Versuchen Sie, den wichtigsten Prozessen (z. B. ssh) eine cgroup-Priorität zuzuweisen, aber dies scheint derzeit für cgroup v1 umständlich zu sein (hoffentlich wird es mit v2 einfacher) ...

Ich fand auch:

Längerfristige Lösung

Warten Sie und hoffen Sie, dass einige Upstream-Patches in stabile Distributionskerne gelangen. Hoffen Sie auch, dass die Distributoren die Kernel-Standardeinstellungen besser anpassen und die systemd-cgroups besser nutzen, um die Reaktionsfähigkeit der Benutzeroberfläche in Desktop-Editionen zu priorisieren.

Einige interessante Patches:

Es liegt also nicht nur an schlechtem User Space Code und Distro Config / Defaults, sondern auch daran, dass der Kernel damit besser umgehen kann.

Kommentare zu bereits berücksichtigten Optionen

1) Deaktivieren Sie den Swap

Es wird empfohlen, mindestens eine kleine Swap-Partition vorzusehen ( Brauchen wir auf modernen Systemen wirklich einen Swap? ). Das Deaktivieren von Swap verhindert nicht nur das Auslagern nicht verwendeter Seiten, sondern wirkt sich auch auf die standardmäßige heuristische Überlastungsstrategie des Kernels für die Speicherzuweisung aus ( Was bedeuten Heuristiken in Overcommit_memory = 0? ), Da diese Heuristik für Auslagerungsseiten zählt. Ohne Swap kann Overcommit wahrscheinlich immer noch im heuristischen Modus (0) oder im Always-Modus (1) funktionieren, aber die Kombination aus No-Swap und Never-Overcommit-Strategie (2) ist wahrscheinlich eine schreckliche Idee. Daher wird in den meisten Fällen kein Swap die Performance beeinträchtigen.

Denken Sie beispielsweise an einen Prozess mit langer Laufzeit, der zunächst den Speicher für einmalige Arbeiten berührt, diesen Speicher dann jedoch nicht freigibt und den Hintergrund weiterhin ausführt. Der Kernel muss dafür RAM verwenden, bis der Prozess endet. Ohne Tausch kann der Kernel keine Seite für etwas anderes erstellen, das den Arbeitsspeicher tatsächlich aktiv nutzen möchte. Denken Sie auch daran, wie viele Entwickler faul sind und nach der Verwendung nicht explizit Speicher freigeben.

3) Stellen Sie ein maximales Speicherlimit ein

Es gilt nur pro Prozess, und es ist wahrscheinlich eine vernünftige Annahme, dass ein Prozess nicht mehr Speicher anfordern sollte, als ein System physisch hat! So ist es wahrscheinlich nützlich, einen einsamen verrückten Prozess davon abzuhalten, Thrashing auszulösen, während er noch großzügig eingestellt ist.

4) Wichtige Programme (X11, bash, kill, top, ...) im Speicher behalten und niemals austauschen

Gute Idee, aber dann werden diese Programme den Speicher sprengen, den sie nicht aktiv nutzen. Es kann akzeptabel sein, wenn das Programm nur eine bescheidene Speichermenge anfordert.

Das Release von systemd 232 hat gerade einige Optionen hinzugefügt, die dies ermöglichen: Ich denke, man könnte mit 'MemorySwapMax = 0' verhindern, dass eine Einheit (ein Dienst) wie ssh irgendeinen Speicher auslagert.

Es wäre jedoch besser, den Speicherzugriff priorisieren zu können.

Lange Erklärung

Der Linux-Kernel ist besser auf Server-Workloads abgestimmt, sodass die Reaktionsfähigkeit der Benutzeroberfläche leider nur eine untergeordnete Rolle spielt. Es entspricht sogar den Standardeinstellungen in RHEL / CentOS 7.2, die normalerweise als Server verwendet werden.

OOM, Ulimit und Kompromiss zwischen Integrität und Reaktionsfähigkeit

Swap-Thrashing (wenn die Arbeitsspeichermenge, dh die Seiten, die in einem bestimmten kurzen Zeitraum gelesen und beschrieben werden, den physischen Arbeitsspeicher überschreiten) sperrt immer die Speicher-E / A - kein Kernel-Assistent kann ein System davon abspeichern, ohne einen Prozess zu beenden oder zwei...

Ich hoffe, dass Linux-OOM-Optimierungen in neueren Kerneln erkennen, dass dieser Arbeitssatz die physische Speichersituation überschreitet und einen Prozess abbricht. Wenn dies nicht der Fall ist, tritt das Thrashing-Problem auf. Das Problem ist, dass es bei einer großen Swap-Partition so aussehen kann, als ob das System noch Headroom hat, während der Kernel fröhlich Commits ausführt und weiterhin Speicheranforderungen bedient, aber die Arbeitsgruppe könnte in Swap übergehen und effektiv versuchen, den Speicher so zu behandeln, als ob Es ist RAM.

Auf Servern akzeptiert es die Performance-Einbußen, wenn für einen entschlossenen, langsamen, nicht verlorenen Daten-Kompromiss gekämpft wird. Auf Desktops ist der Kompromiss unterschiedlich, und Benutzer würden einen Datenverlust (Prozessopfer) vorziehen, um die Reaktionsfähigkeit zu gewährleisten.

Dies war eine nette komische Analogie zu OOM: oom_pardon, aka töte mein xlock nicht

Übrigens OOMScoreAdjustwird eine weitere systembezogene Option zur Gewichtsreduzierung und Vermeidung von OOM-Tötungsprozessen als wichtiger angesehen.

gepuffertes Rückschreiben

Ich denke, " Hintergrund-Rückschreiben nicht saugen lassen " hilft, einige Probleme zu vermeiden, bei denen ein Prozess, der den RAM überlastet, ein weiteres Auslagern (Schreiben auf die Festplatte) verursacht und der Bulk-Schreibvorgang auf die Festplatte alles andere blockiert, was E / A benötigt. Es ist nicht das eigentliche Problem, das die Ursache für das Thrashen ist, aber es trägt zur allgemeinen Verschlechterung der Reaktionsfähigkeit bei.

Begrenzung

Ein Problem bei ulimits besteht darin, dass für den Adressraum des virtuellen Speichers eine Beschränkung gilt (was das Kombinieren von physischem und Swap-Raum impliziert). Wie pro man limits.conf:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

Das Setzen eines ulimits, das nur auf die physische RAM-Nutzung angewendet wird, scheint also nicht mehr verwendbar zu sein. Daher

      as
          address space limit (KB)

scheint das einzig angesehene tunable zu sein.

Leider können einige Anwendungen nicht ausgeführt werden, wie am Beispiel von WebKit / Gnome näher erläutert wird, wenn die Zuweisung des virtuellen Adressraums begrenzt ist.

cgroups soll in zukunft helfen?

Derzeit scheint es umständlich, aber möglich, einige Kernel-cgroup-Flags zu aktivieren cgroup_enable=memory swapaccount=1(z. B. in grub config) und dann den cgroup-Speichercontroller zu verwenden, um die Speichernutzung zu begrenzen.

cgroups verfügen über erweiterte Speicherbegrenzungsfunktionen als die Optionen 'ulimit'. CGroup v2 gibt Hinweise auf Versuche, die Funktionsweise von ulimits zu verbessern.

Die kombinierte Speicher- und Swap-Abrechnung und -Begrenzung wird durch eine echte Kontrolle über den Swap-Bereich ersetzt.

CGroup-Optionen können über systemd-Ressourcensteuerungsoptionen festgelegt werden . Z.B:

  • MemoryHigh
  • MemoryMax

Andere nützliche Optionen könnten sein

  • IOWeight
  • CPUShares

Diese haben einige Nachteile:

  1. Overhead. In der aktuellen Docker-Dokumentation wird kurz 1% zusätzliche Speichernutzung und 10% Leistungseinbußen erwähnt (wahrscheinlich im Hinblick auf Speicherzuweisungsvorgänge - es wird nicht wirklich angegeben).
  2. Das Cgroup / Systemd-Zeug wurde in letzter Zeit stark überarbeitet, so dass die Linux-Distributoren aufgrund des Upstream-Flusses möglicherweise darauf warten, dass es sich als erstes erledigt.

In CGroup v2 wird empfohlen , memory.highdie Speichernutzung einer Prozessgruppe zu drosseln und zu verwalten. Dieses Zitat legt jedoch nahe, dass das Überwachen von Speicherdrucksituationen mehr Arbeit erforderte (ab 2015).

Ein Maß für den Speicherdruck - wie stark die Arbeitslast aufgrund von Speichermangel beeinträchtigt wird - ist erforderlich, um festzustellen, ob eine Arbeitslast mehr Speicher benötigt. Leider ist der Mechanismus zur Überwachung des Speicherdrucks noch nicht implementiert.

Angesichts der Komplexität der User-Space-Tools von systemd und cgroup habe ich keinen einfachen Weg gefunden, um etwas Angemessenes festzulegen und dies weiter zu nutzen. Die Dokumentation zu cgroup und systemd für Ubuntu ist nicht großartig. Zukünftige Arbeiten sollten für Distributionen mit Desktop-Editionen die Nutzung von cgroups und systemd sein, damit ssh und die X-Server / Window-Manager-Komponenten unter hohem Speicherdruck vorrangig auf CPU, physischen RAM und Speicher-E / A zugreifen können, um nicht mit den Prozessen zu konkurrieren beschäftigt tauschen. Die CPU- und E / A-Prioritätsfunktionen des Kernels gibt es schon seit einiger Zeit. Es scheint ein vorrangiger Zugriff auf den physischen Arbeitsspeicher zu sein, der fehlt.

Allerdings sind auch CPU- und IO-Prioritäten nicht richtig eingestellt !? Als ich die systemd cgroup-Limits, CPU-Freigaben usw. überprüfte, hatte Ubuntu, soweit ich sehen konnte, keine vordefinierten Priorisierungen vorgenommen. ZB lief ich:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

Ich habe das mit der gleichen Ausgabe für ssh, samba, gdm und nginx verglichen. Wichtige Dinge wie die grafische Benutzeroberfläche und die Remote-Administrationskonsole müssen beim Thrashen gleichermaßen mit allen anderen Prozessen kämpfen.

Beispielspeicherbeschränkungen, die ich auf einem 16GB RAM System habe

Ich wollte den Ruhezustand aktivieren, also brauchte ich eine große Swap-Partition. Daher versuchen, mit ulimits usw. zu mildern.

ulimit

Ich habe * hard as 16777216in /etc/security/limits.d/mem.confso dass kein einzelner Prozess erlaubt würde mehr Speicher anzufordern , als physikalisch möglich ist. Ich werde nicht verhindern, dass alle zusammen verprügelt werden, aber ohne kann nur ein einziger Prozess mit gieriger Speichernutzung oder einem Speicherverlust zu Verprügelungen führen. ZB habe ich gesehen gnome-contacts, wie 8 GB + Arbeitsspeicher aufgebraucht wurden, wenn alltägliche Dinge wie das Aktualisieren der globalen Adressliste von einem Exchange-Server aus durchgeführt wurden ...

Gnome-Kontakte, die RAM zerkauen

Wie man sieht ulimit -S -v, haben viele Distributionen dieses Hard- und Soft-Limit als "unbegrenzt" festgelegt. Theoretisch könnte ein Prozess viel Speicher anfordern, aber nur aktiv eine Teilmenge verwenden und glücklich davon ausgehen, dass 24 GB RAM zur Verfügung stehen Das System hat nur 16 GB. Das obige harte Limit führt dazu, dass Prozesse, die möglicherweise fehlerfrei ausgeführt wurden, abgebrochen werden, wenn der Kernel seine gierigen spekulativen Speicheranforderungen ablehnt.

Es werden jedoch auch verrückte Dinge wie Gnomenkontakte abgefangen, und anstatt die Reaktionsfähigkeit meines Desktops zu verlieren, wird der Fehler "Nicht genügend freier Speicher" angezeigt:

Bildbeschreibung hier eingeben

Komplikationen beim Setzen des ulimit für den Adressraum (virtueller Speicher)

Leider geben manche Entwickler gerne vor, der virtuelle Speicher sei eine unendliche Ressource, und das Setzen eines Grenzwerts für den virtuellen Speicher kann einige Apps beschädigen. ZB WebKit (von dem einige Gnome-Apps abhängen) hat eine gigacageSicherheitsfunktion hinzugefügt, die versucht, verrückte Mengen an virtuellem Speicher zuzuweisen, und FATAL: Could not allocate gigacage memoryFehler mit einem frechen Hinweis Make sure you have not set a virtual memory limitpassieren. Die Umgehung,GIGACAGE_ENABLED=noDer Verzicht auf die Sicherheitsvorteile, aber auch der Verzicht auf ein Sicherheitsmerkmal (z. B. eine Ressourcensteuerung, die Denial-of-Service verhindern kann), ohne die Zuweisung von virtuellem Speicher einschränken zu dürfen. Ironischerweise scheinen sie zwischen Gigacage- und Gnome-Entwicklern zu vergessen, dass die Begrenzung der Speicherzuweisung selbst eine Sicherheitskontrolle ist. Und leider ist mir aufgefallen, dass die Gnome-Apps, die auf Gigacage basieren, keine explizite Anforderung eines höheren Limits haben, sodass in diesem Fall sogar ein weiches Limit die Dinge kaputt macht.

Um ehrlich zu sein, wäre es weniger gefährlich, wenn der Kernel die Speicherzuweisung auf der Grundlage der Nutzung des residenten Speichers anstelle des virtuellen Speichers ablehnen könnte.

überbeanspruchen

Wenn Sie es vorziehen, Anwendungen den Speicherzugriff zu verweigern und das Overcommitting zu beenden, testen Sie mit den folgenden Befehlen, wie sich Ihr System bei hohem Speicherdruck verhält.

In meinem Fall war das Standard-Commit-Verhältnis:

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

Sie wird jedoch erst dann vollständig wirksam, wenn Sie die Richtlinie ändern, um das Overcommiting zu deaktivieren und das Verhältnis anzuwenden

sudo sysctl -w vm.overcommit_memory=2

Dem implizierten Verhältnis konnten insgesamt nur 24 GB Speicher zugewiesen werden (16 GB RAM * 0,5 + 16 GB SWAP). Daher wird OOM wahrscheinlich nie angezeigt, und es ist weniger wahrscheinlich, dass Prozesse beim Auslagern ständig auf den Speicher zugreifen. Aber ich werde wahrscheinlich auch die Gesamtsystemeffizienz opfern.

Dies führt dazu, dass viele Anwendungen abstürzen, da Entwickler das Betriebssystem, das eine Speicherzuweisungsanforderung ablehnt, häufig nicht ordnungsgemäß verarbeiten. Das gelegentliche Risiko eines langwierigen Absturzes aufgrund von Thrashing (Verlust all Ihrer Arbeit nach einem Hard-Reset) wird gegen das häufigere Risiko eines Absturzes verschiedener Apps eingetauscht. In meinen Tests hat es nicht viel geholfen, da der Desktop selbst abstürzte, wenn das System unter Speicherdruck stand und Speicher nicht zugewiesen werden konnte. Zumindest Konsolen und SSH funktionierten jedoch noch.

Weitere Informationen zur Funktionsweise von VM-Overcommit-Speicher finden Sie hier.

Da sudo sysctl -w vm.overcommit_memory=0der gesamte grafische Desktop-Stapel und die darin enthaltenen Anwendungen dennoch abstürzen, habe ich mich dafür entschieden, die Standardeinstellungen wiederherzustellen.

JPvRiel
quelle
3
Dies ist die beste Beschreibung, die ich zu diesem Thema gesehen habe, und Sie greifen nicht auf "Kaufen Sie einfach mehr RAM!" Eine Sache, die Sie nicht erwähnen, ist die Art und Weise, wie die Kernel-Konfigurationsoptionen diesbezüglich funktionieren. Würde beispielsweise das verwendete Präemtionsmodell oder der verwendete E / A-Scheduler einen wesentlichen Einfluss darauf haben?
Hololeap
2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. Gibt es dafür Beweise? Ich glaube, Kernel-
Overcommits funktionieren
@ygrek, danke, diese Formulierung sieht ein bisschen falsch aus - Overcommit funktioniert immer noch ohne Swap, es sei denn, der Never Overcommit-Modus (2) ist ausgewählt. Die Standardmodi für heuristisches Overcommit (0) oder immer Commit (1) funktionieren wahrscheinlich immer noch ohne Swap. Ich kann mich nicht erinnern, wo ich gelesen habe, dass das Deaktivieren von Swap die Fähigkeit des Overcommit-Codes beeinträchtigt, Speicher zuzuweisen (und welchen Modus es speziell betrifft). Wieder ohne Glück gegoogelt, aber dies war ein halbwegs nützlicher Beitrag: stackoverflow.com/questions/38688824/… Ich werde die Antwort entsprechend bearbeiten.
JPvRiel
Ich hatte gehofft, dass der Writeback-Patch im Hintergrund mir helfen würde, aber ich bin auf einem sehr neuen Kernel (4.14.81) und habe erhebliche Probleme mit der Reaktionsfähigkeit unter E / A-Last (unabhängig davon, ob Swap die Ursache ist oder nicht). Ich frage mich, ob der Geräte-Manager oder meine LUKS-Verschlüsselung Leistungsprobleme verursachen. Ich habe wirklich wenig Ahnung, wie man solche Probleme behebt.
Darius Jahandarie