4 Stimmen

Warum wird bei Diskussionen über "Swappiness" so getan, als könnten Informationen nur an einem Ort gleichzeitig sein?

Ich habe mich über die "Swappiness"-Einstellung von Linux informiert, die steuert, wie aggressiv der Kernel den Speicher von Anwendungen auf die Festplatte auslagert, wenn sie nicht benutzt werden. Wenn man den Begriff googelt, erhält man eine Menge Seiten wie ce das Für und Wider zu diskutieren. Kurz gesagt, das Argument lautet wie folgt:

Wenn Ihr Swappiness-Wert zu niedrig ist, belegen inaktive Anwendungen den gesamten Systemspeicher, den andere Programme nutzen möchten.

Wenn die Auslagerungsrate zu hoch ist, kommt es beim Aufwecken der inaktiven Anwendungen zu einer großen Verzögerung, da ihr Status von der Festplatte zurückgelesen wird.

Dieses Argument ist für mich nicht nachvollziehbar. Wenn ich eine inaktive Anwendung habe, die eine Menge Speicher verbraucht, warum paginiert der Kernel dann nicht seinen Speicher auf die Festplatte UND lässt eine weitere Kopie dieser Daten im Speicher? Das scheint das Beste aus beiden Welten zu sein: Wenn eine andere Anwendung diesen Speicher benötigt, kann sie sofort den physischen RAM beanspruchen und anfangen, darauf zu schreiben, da eine andere Kopie davon auf der Festplatte liegt und zurück ausgelagert werden kann, wenn die inaktive Anwendung aufgeweckt wird. Und wenn die ursprüngliche Anwendung aufwacht, können alle ihre Seiten, die sich noch im RAM befinden, unverändert verwendet werden, ohne dass sie von der Festplatte geholt werden müssen.

Oder übersehe ich etwas?

3voto

DGentry Punkte 15830

Wenn ich eine inaktive Anwendung habe, die eine Menge Speicher verbraucht, warum paginiert der Kernel den Speicher nicht auf die Festplatte UND lässt eine weitere Kopie dieser Daten im Speicher?

Nehmen wir an, wir haben es geschafft. Wir haben die Seite auf die Festplatte geschrieben, sie aber im Speicher belassen. Einige Zeit später benötigt ein anderer Prozess Speicher, also wollen wir die Seite aus dem ersten Prozess herauswerfen.

Wir müssen mit absoluter Sicherheit wissen, ob der erste Prozess die Seite verändert hat, seit sie auf die Festplatte geschrieben wurde. Wenn dies der Fall ist, müssen wir sie erneut ausschreiben. Die Art und Weise, wie wir dies nachverfolgen können, besteht darin, dem Prozess die Schreibberechtigung für die Seite zu entziehen, als wir sie zum ersten Mal auf die Festplatte geschrieben haben. Wenn der Prozess erneut versucht, auf die Seite zu schreiben, kommt es zu einem Seitenfehler. Der Kernel kann feststellen, dass der Prozess die Seite verschmutzt hat (und daher erneut geschrieben werden muss), bevor er die Schreibberechtigung wiederherstellt und der Anwendung erlaubt, fortzufahren.

Genau hier liegt das Problem. Der Seite die Schreibberechtigung zu entziehen, ist in der Tat ziemlich teuer, insbesondere bei Multiprozessor-Maschinen. Es ist wichtig, dass alle CPUs ihren Cache von Seitenübersetzungen bereinigen, um sicherzustellen, dass sie die Schreibberechtigung wegnehmen.

Wenn der Prozess auf die Seite schreibt, ist das Auftreten eines Seitenfehlers noch teurer. Ich nehme an, dass eine nicht-triviale Anzahl dieser Seiten am Ende diesen Fehler erleiden würde, was die Gewinne auffrisst, die wir durch das Belassen der Seite im Speicher erzielen wollten.

Lohnt es sich also, das zu tun? Ich weiß es ehrlich gesagt nicht. Ich versuche nur zu erklären, warum das Belassen der Seite im Speicher kein so offensichtlicher Gewinn ist, wie es klingt.

(*) Das Ganze ist einem Mechanismus namens Copy-On-Write sehr ähnlich, der verwendet wird, wenn sich ein Prozess aufspaltet()s. Der Kindprozess wird höchstwahrscheinlich nur ein paar Anweisungen ausführen und exec() aufrufen, so dass es dumm wäre, alle Seiten des Elternprozesses zu kopieren. Stattdessen wird dem Kindprozess die Schreibberechtigung entzogen und er darf einfach laufen. Copy-On-Write ist ein Gewinn, weil der Page Fault fast nie genommen wird: das Kind ruft fast immer sofort exec() auf.

1voto

Dprado Punkte 1550

Selbst wenn Sie den Anwendungsspeicher auf die Festplatte auslagern und im Speicher behalten, müssen Sie immer noch entscheiden, wann eine Anwendung als "inaktiv" betrachtet werden soll, und das wird durch die Auslagerungsfähigkeit gesteuert. Das Auslagern auf die Festplatte ist teuer in Bezug auf IO und man möchte es nicht zu oft machen. Es gibt noch eine weitere Variable in dieser Gleichung, und zwar die Tatsache, dass Linux den verbleibenden Speicher als Festplattenpuffer/Cache verwendet.

0voto

BillTorpey Punkte 861

Demnach 1 Das ist genau das, was Linux tut.

Ich versuche immer noch, mir einen Reim auf all das zu machen, daher wäre ich für jeden maßgeblichen Link dankbar.

0voto

Als erstes bereinigt die VM die Seiten und verschiebt sie in die Bereinigungsliste.
Beim Bereinigen von anonymem Speicher (Dinge, die keinen tatsächlichen Dateispeicher haben, Sie können die Segmente in /proc//maps sehen, die anonym sind und keinen Dateisystem-Vnode-Speicher hinter sich haben), ist das erste, was die VM tun wird, die "schmutzigen" Seiten zu nehmen und dann zu "bereinigen", indem sie den Inhalt der Seite in den Swap-Bereich schreibt. Wenn die VM nun einen Mangel an völlig freiem Speicher hat und sich Sorgen um ihre Fähigkeit macht, neue freie Seiten zur Verwendung zuzulassen, kann sie die Liste der "sauberen" Seiten durchgehen und basierend darauf, wie kürzlich sie verwendet wurden und um welche Art von Speicher es sich handelt, diese Seiten in die Liste der freien Seiten verschieben.

Sobald die Speicherseiten auf die Liste der freien Seiten gesetzt werden, sind sie nicht mehr mit dem Inhalt verbunden, den sie vorher hatten. Wenn ein Programm auf den Speicherplatz verweist, den die Seite vorher hatte, wird das Programm einen großen Fehler machen und eine (höchstwahrscheinlich völlig andere) Seite aus der freien Liste nehmen und die Daten von der Festplatte in die Seite einlesen. Sobald dies geschehen ist, ist die Seite eigentlich immer noch "sauber", da sie nicht verändert wurde. Wenn sich die VM entscheidet, diese Seite im Swap für eine andere Seite im RAM zu verwenden, wird die Seite erneut "verschmutzt", oder wenn die Anwendung auf diese Seite schreibt, wird sie "verschmutzt". Und dann beginnt der Prozess von vorne.

Außerdem ist Swappinness für Serveranwendungen in einer Geschäfts-/Transaktions-/Online-/Latenz-abhängigen Umgebung ziemlich schrecklich. Wenn ich 16-GB-RAM-Boxen habe, auf denen ich nicht viele Browser und GUIs ausführe, möchte ich normalerweise, dass alle meine Anwendungen fast im Speicher verankert sind. Der Großteil meines RAMs besteht aus 8-10 GB großen Java-Haufen, die ich NIEMALS auf die Festplatte ausgelagert werden, und der Müll, der verfügbar ist, sind Prozesse wie mingetty (aber selbst dort werden die Glibc-Seiten in diesen Anwendungen von anderen Anwendungen gemeinsam genutzt und tatsächlich verwendet, so dass sogar die RSS-Größe dieser nutzlosen Prozesse größtenteils gemeinsam genutzte Seiten sind). Normalerweise sehe ich nicht mehr als ein paar 10 MB der 16 GB, die tatsächlich in den Swap-Bereich verschoben werden. Ich würde zu sehr, sehr niedrigen Swappiness-Zahlen oder Null-Swappiness für Server raten - die ungenutzten Seiten sollten nur einen kleinen Teil des gesamten RAM ausmachen, und der Versuch, diese relativ winzige Menge an RAM für den Puffercache zurückzugewinnen, birgt das Risiko, Anwendungsseiten auszulagern und Latenzzeiten in der laufenden Anwendung in Kauf zu nehmen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X