Verhindern Sie das Einfrieren / Nicht-Reagieren des Systems aufgrund von Speicherauslastung durch Auslagern

11759
BeniBela

Wenn ein Prozess viel Speicher benötigt, werden alle anderen Prozesse in die Auslagerungsdatei verschoben. Darunter scheinen 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 abgebrochen wird. Mein Laptop scheint besonders vernünftig zu sein und reagiert extrem schlecht. Ich habe nur eine ganze Stunde auf die Beendigung des Prozesses gewartet, während der nicht einmal der Mauszeiger bewegt werden konnte.

Wie kann das vermieden werden?

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

2) Hol dir eine SSD => zu teuer

3) Setzen Sie einen maximalen Speicher ulimit =>, der jedoch fehlschlägt, wenn ein Programm einen vernünftigen, großen Speicherplatz benötigt. Das Problem ist nicht, dass es zu viel verwendet wird, sondern dass es die anderen Prozesse unterdrückt

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

5)

29
Und ti passierte wieder :( GCC wurde gestartet, während Firefox lief, eine halbe Stunde lang war alles blockiert. Keine Mausbewegungen, kein E-Book-Lesen BeniBela vor 7 Jahren 0
Ich bin mir nicht sicher, was ich will. Möchten Sie, dass das System mit den vorhandenen Ressourcen auf magische Weise zaubert? Möchten Sie, dass Prozesse, die viel Speicher benötigen, früher beendet werden? David Schwartz vor 7 Jahren 0
Klingt wie Sie wirklich mehr RAM benötigen. Oder weniger "inaktive" Hintergrundaufgaben. Daniel B vor 7 Jahren 0
Sie können die Tastenkombination [Alt + SysRq + F] (https://www.reddit.com/r/linux/comments/75gyrz/a_tribute_to_altsysrqf/) verwenden, um die Ausführung des OOM-Killers zu erzwingen. Auf diese Weise können Sie nicht so lange warten, bis Ihr System eine Konsole öffnet, um einen Prozess zu beenden. hololeap vor 6 Jahren 0
Korrigieren Sie mich, wenn ich falsch liege, aber dieses Problem klingt tatsächlich so, als würde das System nach Plattenspeicherplatz suchen, der vorhanden sein sollte, aber nicht vorhanden ist (Swap-Partition ist zu klein). Wenn nicht genügend Swap-Speicherplatz vorhanden ist, wird das Festplattenlaufwerk (oder SSD-Laufwerk) vom System nach Speicherplatz durchsucht. mchid vor 6 Jahren 0

1 Antwort auf die Frage

27
JPvRiel

TL; DR

Kurzzeit / Antwort

  • Am einfachsten : Haben Sie eine kleinere Swap-Partition und vermeiden Sie, dass der Kernel versucht, der Lüge nachzukommen, dass es keine Speicherbegrenzung gibt, indem Prozesse aus langsamem Speicher ausgeführt werden.
    • Bei einem großen Swap greift der OOM (Out of Memory Manager) nicht schnell genug ein. Normalerweise rechnet es nach virtuellem Speicher und hat in meiner bisherigen Erfahrung keine Dinge getötet, bis der gesamte Swap gefüllt war, daher das System des Dreschens und Krieges ...
  • Brauchen Sie einen großen Swap für den Winterschlaf?
    • Versucht / Problematisch : Legen Sie einige ulimits fest (z. B. prüfen Sie ulimit -vmit der asOption in ein hartes oder weiches Limit limits.conf). Früher hat das gut funktioniert, aber dank der Einführung von WebKit gigacageerwarten viele gnome-Apps jetzt unbegrenzte Adressräume und laufen nicht!
    • 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, die wichtigsten Prozesse (z. B. ssh) mit einer cgroup-Priorität zu versehen. Dies scheint jedoch derzeit für cgroup v1 umständlich zu sein (hoffentlich wird v2 es einfacher machen) ...

Ich habe auch gefunden:

Längerfristige Lösung

Warten Sie und hoffen Sie auf einige Upstream-Patches, um stabile Distributionskerne zu erreichen. Ich hoffe auch, dass Distributoren die Kernel-Standardeinstellungen besser abstimmen und systemd cgroups besser einsetzen, um die GUI-Reaktionsfähigkeit in Desktop-Editionen zu priorisieren.

Einige Flecken von Interesse:

Es liegt also nicht nur an schlechtem Benutzer-Space-Code und an den Distro-Config / Defaults - der Kernel könnte dies besser bewältigen.

Anmerkungen zu bereits berücksichtigten Optionen

1) Deaktivieren Sie den Swap

Es wird empfohlen, mindestens eine kleine Swap-Partition bereitzustellen ( Brauchen wir auf modernen Systemen wirklich einen Swap? ). Durch das Deaktivieren von Swap wird nicht nur das Auslagern nicht verwendeter Seiten verhindert, sondern es kann sich auch auf die Standardstrategie für die zu hohe Heuristik des Kernels für die Speicherzuordnung auswirken ( Was bedeutet Heuristik in Overcommit_memory = 0? ), Da diese Heuristik für Swap-Seiten gilt. Ohne Swap kann Overcommit wahrscheinlich immer noch in den heuristischen (0) oder immer (1) -Modi funktionieren, aber die Kombination von No Swap und der Never (2) Overcommit-Strategie ist wahrscheinlich eine schreckliche Idee. In den meisten Fällen wird also kein Swap die Performance beeinträchtigen.

Denken Sie beispielsweise an einen langwierigen Prozess, der anfänglich den Speicher für einmalige Arbeit berührt, diesen Speicher dann jedoch nicht freigibt und den Hintergrund weiterführt. Der Kernel muss dazu RAM verwenden, bis der Prozess beendet ist. Ohne Swap kann der Kernel nicht nach etwas anderem suchen, das RAM aktiv nutzen möchte. Denken Sie auch darüber nach, wie viele Entwickler faul sind und nach der Verwendung nicht explizit Speicherplatz freigeben.

3) Maximale Speichergröße einstellen

Dies gilt nur für einen Prozess, und es ist wahrscheinlich eine vernünftige Annahme, dass ein Prozess nicht mehr Speicher anfordert, als ein System physisch hat! Daher ist es wahrscheinlich nützlich, zu verhindern, dass ein einzelner verrückter Prozess Thrashing auslöst, während er dennoch großzügig eingestellt ist.

4) Bewahren Sie wichtige Programme (X11, bash, kill, top, ...) im Speicher auf und tauschen Sie diese niemals aus

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

Systemd 232 hat gerade einige Optionen hinzugefügt, die dies möglich machen: Ich denke, man könnte "MemorySwapMax = 0" verwenden, um zu verhindern, dass ein Gerät (Dienst) wie ssh irgendeinen Speicher auslagert.

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

Lange Erklärung

Der Linux-Kernel ist mehr auf Server-Workloads abgestimmt, so dass die GUI-Reaktionsfähigkeit leider ein zweitrangiges Problem war ... Die Einstellungen für die Kernel-Speicherverwaltung auf der Desktop-Edition von Ubuntu 16.04 LTS schienen sich nicht von den anderen Server-Editionen zu unterscheiden. Es stimmt sogar mit den Standardeinstellungen in RHEL / CentOS 7.2 überein, die normalerweise als Server verwendet werden.

OOM, ulimit und Kompromisslosigkeit gegen Reaktionsfähigkeit

Swap-Thrashing (wenn der Arbeitsspeicher, dh Seiten, die innerhalb eines bestimmten Zeitrahmens gelesen und beschrieben werden, den physischen RAM-Speicher überschreitet), wird die Speicher-E / A immer blockiert - keine Kernel-Zauberei kann ein System davon abhalten, ohne einen Prozess zu beenden oder zwei...

Ich hoffe, dass Linux-OOM-Optimierungen, die in neueren Kerneln auftauchen, erkennen, dass dieser Arbeitssatz den physischen Hauptspeicher übersteigt und einen Prozess abbricht. Wenn dies nicht der Fall ist, tritt das Thrash-Problem auf. Das Problem ist, mit einer großen Swap-Partition kann es so aussehen, als ob das System noch über Headroom verfügt, während der Kernel fröhlich übergeht und Speicheranforderungen abdeckt. Das Arbeitsset könnte jedoch in den Swap übergreifen und versuchen, den Speicher effektiv zu behandeln es ist RAM.

Auf Servern akzeptiert es die Leistungseinbußen des Thrashings für einen entschlossenen, langsamen, Datenverlust und Kompromiss. Auf Desktops ist der Kompromiss anders, und Benutzer würden ein wenig Datenverlust (Prozessopfer) vorziehen, um die Reaktionsfähigkeit zu erhalten.

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

Übrigens OOMScoreAdjustist eine weitere systemd Option die Gewichtszunahme und das Vermeiden von OOM-Tötungsprozessen.

gepuffertes Rückschreiben

Ich denke, " Hintergrund-Rückschreiben nicht saugen lassen " wird dazu beitragen, einige Probleme zu vermeiden, bei denen ein Prozess, der den Arbeitsspeicher überlastet, einen anderen Auslagerungsvorgang verursacht (Write-to-Disk) und der Massen-Write-to-Disk-Vorgang alles andere blockiert, wenn IO gewünscht wird. Es ist nicht das eigentliche Problem der Ursache, aber es trägt zur allgemeinen Verschlechterung der Reaktionsfähigkeit bei.

Begrenzung

Ein Problem bei ulimits besteht darin, dass die Abrechnungsgrenze für den Adressraum des virtuellen Speichers gilt (was bedeutet, dass sowohl physischer als auch Swap-Bereich kombiniert werden). Wie pro man limits.conf:

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

Das Festlegen eines ulimit, um nur auf die physische RAM-Nutzung anzuwenden, scheint daher nicht mehr brauchbar zu sein. Daher

 as address space limit (KB) 

scheint der einzig angesehene stimmbare zu sein.

Unglücklicherweise, wie ausführlicher am Beispiel von WebKit / Gnome beschrieben, können einige Anwendungen nicht ausgeführt werden, wenn die virtuelle Adressraumzuweisung begrenzt ist.

cgroups soll in Zukunft helfen?

Momentan scheint es umständlich zu sein, es ist jedoch möglich, einige Kernflags für cgroup zu aktivieren cgroup_enable=memory swapaccount=1(z. B. in grub config) und dann den cgroup-Speichercontroller zu verwenden, um die Speicherbelegung zu begrenzen.

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

Die kombinierte Speicher- und Swap-Abrechnung und -Begrenzung wird durch die tatsächliche Kontrolle des Swap-Bereichs 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ätzlicher Speicherverbrauch und 10% Leistungseinbußen erwähnt (wahrscheinlich im Hinblick auf Speicherzuweisungsoperationen - es gibt keine genauen Angaben dazu).
  2. Cgroup / systemd wurde in letzter Zeit stark überarbeitet, so dass der Upstream des Flusses impliziert, dass Linux-Distributoren darauf warten, dass sie sich zuerst niederlassen.

In CGroup v2 wird vermutet, dass memory.highdies eine gute Option sein sollte, um die Speichernutzung durch eine Prozessgruppe zu drosseln und zu verwalten. Dieses Zitat legt jedoch nahe, dass die Überwachung des Gedächtnisdrucks mehr Arbeit erfordert (ab 2015).

Um zu bestimmen, ob eine Arbeitslast mehr Arbeitsspeicher benötigt, ist ein Maß für den Speicherdruck erforderlich - wie stark sich die Arbeitslast aufgrund von Speichermangel auswirkt. Leider ist der Mechanismus zur Überwachung des Speicherdrucks noch nicht implementiert.

Angesichts der Komplexität der systemd- und cgroup-Werkzeuge für den Benutzerraum gibt es keine einfache Möglichkeit, etwas angemessenes einzustellen und dieses Potenzial weiter auszubauen. Die cgroup- und systemd-Dokumentation für Ubuntu ist nicht so toll. Zukünftige Arbeit sollte für Desktop-Editionen von distro sein, um cgroups und systemd so einzusetzen, dass ssh und die X-Server- / Window-Manager-Komponenten bei hohem Speicherdruck Zugriff auf CPU, physischen Arbeitsspeicher und Speicher-IO mit höherer Priorität erhalten, um einen Wettbewerb mit den Prozessen zu vermeiden beschäftigt tauschen. Die CPU- und E / A-Prioritätsfunktionen des Kernels sind seit einiger Zeit verfügbar. Es scheint der vorrangige Zugriff auf physischen RAM zu sein, der fehlt.

Allerdings sind nicht einmal die CPU- und E / A-Prioritäten entsprechend eingestellt !? Als ich die systemd-Gruppenlimits, CPU-Freigaben usw. überprüft habe, hatte Ubuntu, soweit ich das beurteilen konnte, keine vordefinierten Prioritäten festgelegt. Ich lief zB:

systemctl show dev-mapper-Ubuntu\x2dswap.swap 

Ich verglich das mit der gleichen Ausgabe für ssh, samba, gdm und nginx. Wichtige Dinge wie die grafische Benutzeroberfläche und die Remote-Administrationskonsole müssen bei allen Thrashing-Vorgängen gleichermaßen kämpfen.

Beispiel Speichergrenzen habe ich auf einem 16 GB RAM-System

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 kann das Thrashing nicht alle gemeinsam verhindern, aber ohne einen einzigen Prozess mit gieriger Speichernutzung oder einem Speicherverlust kann Thrashing verursacht werden. ZB habe ich gesehen, gnome-contactswie Speicher 8 GB + gesaugt werden, wenn weltliche Dinge wie das Aktualisieren der globalen Adressliste von einem Exchange-Server durchgeführt werden.

Gnome-Kontakte fressen den RAM auf

Wie man sieht ulimit -S -v, haben viele Distributionen diesen harten und weichen Grenzwert als "unbegrenzt" festgelegt. Theoretisch könnte ein Prozess letztendlich viel Speicher anfordern, aber nur aktiv eine Teilmenge verwenden, wobei er denkt, dass ihm 24 GB RAM gegeben wurden Das System hat nur 16 GB. Das obige harte Limit führt dazu, dass Prozesse, die möglicherweise ordnungsgemäß ausgeführt wurden, abgebrochen werden, wenn der Kernel seine gierigen spekulativen Speicheranforderungen ablehnt.

Es fängt jedoch auch verrückte Dinge wie Gnome-Kontakte an, und anstatt meine Desktop-Reaktionsfähigkeit zu verlieren, erhalte ich die Fehlermeldung "nicht genügend freier Speicher":

Komplikationen für das Festlegen von ulimit für den Adressraum (virtueller Speicher)

Unglücklicherweise geben manche Entwickler vor, virtueller Speicher sei eine unendliche Ressource, und das Festlegen eines ulimit für virtuellen Speicher kann einige Apps beschädigen. ZB WebKit (von dem einige Gnome-Apps abhängig sind) fügte eine gigacageSicherheitsfunktion hinzu, die versucht, wahnsinnige Mengen an virtuellem Speicher zuzuordnen, und FATAL: Could not allocate gigacage memoryFehler mit einem frechen Hinweis Make sure you have not set a virtual memory limitpassieren. Die ProblemumgehungGIGACAGE_ENABLED=noverzichtet auf die Sicherheitsvorteile, aber auch die Einschränkung der Zuweisung von virtuellem Speicher bedeutet nicht, dass ein Sicherheitsmerkmal (z. B. eine Ressourcenkontrolle, die Denial-of-Service verhindern kann) fehlt. Ironischerweise scheinen sie zwischen Gigacage und Gnome-Entwicklern zu vergessen, dass die Begrenzung der Speicherzuordnung selbst eine Sicherheitssteuerung darstellt. Und leider bemerkte ich, dass die Gnome-Apps, die auf Gigacage angewiesen sind, nicht explizit ein höheres Limit fordern. In diesem Fall bricht sogar ein weiches Limit die Dinge.

Um ehrlich zu sein, wenn der Kernel es besser geschafft hat, die Speicherzuweisung auf der Grundlage der Verwendung des residenten Speichers anstelle des virtuellen Speichers zu verweigern, dann wäre das Vorgeben von virtuellem Speicher unbegrenzt weniger gefährlich.

Übererfüllung

Wenn Sie bevorzugen, dass Anwendungen den Speicherzugriff verweigern, und die Überbindung beenden möchten, verwenden Sie die folgenden Befehle, um zu testen, wie sich Ihr System bei hohem Speicherdruck verhält.

In meinem Fall war die Default-Commit-Ratio:

$ sysctl vm.overcommit_ratio vm.overcommit_ratio = 50 

Dies wird jedoch nur dann wirksam, wenn Sie die Richtlinie ändern, um die Überlastung zu deaktivieren und das Verhältnis anzuwenden

sudo sysctl -w vm.overcommit_memory=2 

Das Verhältnis implizierte, dass nur 24 GB Speicher insgesamt zugewiesen werden konnten (16 GB RAM * 0,5 + 16 GB SWAP). Ich würde also wahrscheinlich nie OOM auftauchen sehen und effektiv wäre es unwahrscheinlich, dass Prozesse ständig auf den Speicher im Swap zugreifen. Ich werde aber wahrscheinlich auch die Gesamtsystemeffizienz opfern.

Dies führt zum Absturz vieler Anwendungen, da Devs normalerweise nicht ordnungsgemäß mit dem Betriebssystem umgehen, das eine Speicherzuordnungsanforderung ablehnt. Das gelegentliche Risiko einer langwierigen Überbrückung aufgrund von Thrashing (all Ihre Arbeit nach einem Hard Reset) wird durch ein häufigeres Risiko des Absturzes verschiedener Apps ersetzt. In meinen Tests half es nicht viel, da der Desktop selbst abstürzte, als das System unter Speicherdruck stand und der Speicher nicht zugewiesen werden konnte. Zumindest Konsolen und SSH funktionierten trotzdem.

Wie funktioniert die VM-Überlastungsspeicherfunktion mehr Informationen?

Ich entschied mich dafür, zum Standard zurückzukehren sudo sysctl -w vm.overcommit_memory=0, da der gesamte grafische Desktop-Stack und die darin enthaltenen Anwendungen trotzdem abstürzen.

Dies ist der beste Bericht, den ich zu diesem Thema gesehen habe, und Sie greifen nicht zu "kaufen Sie einfach mehr RAM!" Eine Sache, die Sie nicht erwähnen, ist die Art und Weise, wie die Kernel-Konfigurationsoptionen dazu beitragen. Würde beispielsweise das verwendete Präemtionsmodell oder der verwendete E / A-Scheduler einen großen Einfluss auf irgendetwas davon haben? hololeap vor 6 Jahren 0
`Der Kernel kann jedoch keine Overcommit-Strategie für die Zuweisung von Speicher verwenden, was die Performance beeinträchtigen könnte. Sogar eine kleinere Swap-Partition erlaubt dies.` Gibt es einen Beweis dafür? Ich glaube, Kernel-Overcommits sind gut ohne Swap konfiguriert ygrek vor 5 Jahren 1
@ ygrek, danke, dass die Formulierung ziemlich falsch aussieht - overcommit funktioniert auch ohne Swap, es sei denn, der Modus overcommit (2) ist nie ausgewählt. Der standardmäßige heuristische Übercommit-Modus (0) oder der Commit-Modus (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 Überbeanspruchungscodes beeinträchtigt, Speicher zuzuweisen (und welchen Modus er speziell beeinflusst hat). Ohne Glück wieder gegoogelt, aber dies war ein halbwegs nützlicher Beitrag: https://stackoverflow.com/questions/38688824/linux-over-commit-heuristic. Ich werde die Antwort entsprechend bearbeiten. JPvRiel vor 5 Jahren 0
Ich hatte gehofft, dass der Hintergrund-Writeback-Patch mir helfen würde, aber ich befinde mich in einem sehr neuen Kernel (4.14.81) und stehe unter schwerwiegenden Festplatten-I / O-Problemen (unabhängig davon, ob Swap die Ursache ist oder nicht). Ich frage mich, ob der Geräte-Manager oder meine LUKS-Verschlüsselung irgendwie zu Leistungsproblemen führen. Ich habe wirklich keine Ahnung, wie ich diese Art von Problem beheben kann. Darius Jahandarie vor 5 Jahren 0