Wie funktioniert vm.overcommit_memory?

49

Wenn ich die Standardeinstellungen verwende:

vm.overcommit_memory = 0
vm.overcommit_ratio = 50

Ich kann diese Werte aus der /proc/meminfoDatei lesen :

CommitLimit:     2609604 kB
Committed_AS:    1579976 kB

Aber wenn ich vm.overcommit_memoryvon 0zu ändere , 2kann ich nicht die gleichen Anwendungen starten, die ich vor der Änderung starten konnte, insbesondere Amarok. Ich musste ändern vm.overcommit_ratiozu 300, so dass die Grenze erhöht werden kann. Wenn ich nun Amarok starte, /proc/meminfozeigt sich folgendes:

CommitLimit:     5171884 kB
Committed_AS:    3929668 kB

Diese Maschine hat nur 1 GB RAM, aber amarok funktioniert ohne Probleme, wenn vm.overcommit_memoryes auf 0 gesetzt ist. Wenn es jedoch auf 0 gesetzt ist 2, muss amarok mehr als 2 GB Arbeitsspeicher zuweisen. Ist es ein normales Verhalten? Wenn ja, kann jemand erklären, warum beispielsweise Firefox (das 4-6x mehr Speicher als Amarok belegt) vor und nach der Änderung auf die gleiche Weise funktioniert?

Mikhail Morfikov
quelle

Antworten:

66

Sie finden die Dokumentation in man 5 proc( oder auf kernel.org ):

/proc/sys/vm/overcommit_memory
       This file contains the kernel virtual memory accounting mode.
       Values are:

              0: heuristic overcommit (this is the default)
              1: always overcommit, never check
              2: always check, never overcommit

       In mode 0, calls of mmap(2) with MAP_NORESERVE are not
       checked, and the default check is very weak, leading to the
       risk of getting a process "OOM-killed".

       In mode 2 (available since Linux 2.6), the total virtual
       address space that can be allocated (CommitLimit in /proc/mem‐
       info) is calculated as

           CommitLimit = (total_RAM - total_huge_TLB) *
                         overcommit_ratio / 100 + total_swap

Die einfache Antwort ist, dass das Setzen von overcommit auf 1 die Bühne so einstellt, dass es immer erfolgreich ist , wenn ein Programm etwas aufruft malloc(), um einen Teil des Speichers zuzuweisen ( man 3 malloc), unabhängig davon, ob das System weiß, dass nicht der gesamte Speicher vorhanden ist gefragt.

Das zugrunde liegende Konzept ist die Idee des virtuellen Speichers . Programme sehen einen virtuellen Adressraum, der möglicherweise dem tatsächlichen physischen Speicher zugeordnet ist. Durch Deaktivieren der Überlastungsprüfung weisen Sie das Betriebssystem an, nur anzunehmen, dass immer genügend physischer Speicher vorhanden ist, um den virtuellen Speicherplatz zu sichern.

Beispiel

Um herauszufinden, warum dies manchmal wichtig sein kann, werfen Sie einen Blick auf die Redis-Anleitungen, warum vm.overcommit_memorydies auf 1 gesetzt werden sollte.

Kyle Brandt
quelle
2
Aber sollte der Wert Committed_ASnicht in beiden Fällen gleich sein?
Mikhail Morfikov
@MikhailMorfikov: Theoretisch glaube ich schon, aber wer weiß, was diese Programme tun. Möchten Sie eine kontrollierte Umgebung mit einem einfachen Programm sehen, das nur einen Gig RAM über Malloc zuweist. Führen Sie den Test nach dem Neustart zwischen den Tests aus.
Kyle Brandt
Ok, also bleibe ich vorerst bei 0.
Mikhail Morfikov
2
@MikhailMorfikov: Ja, praktisch finde ich 0 am sinnvollsten. In meiner Umgebung ist das einzige Mal, dass ich 1 aktiviere, Redis, das erwartet , dass es aufgrund einer Fork () viel mehr Speicher benötigt. Das Kind wird so ziemlich alle Speicherseiten verwenden, aber Linux weiß nicht, dass es sicherheitshalber davon ausgehen muss, dass 2x Speicher verwendet wird (wenn Sie mehr erfahren möchten: redis.io/topics/faq )
Kyle Brandt
Sollte die letzte Anweisung in Ihrer Antwort nicht wie folgt beginnen: "Durch Aktivieren von Überbeanspruchung"? Wenn Sie den Wert auf 1 setzen, werden Sie aufgefordert, eine Überbeanspruchung durchzuführen, oder?
Asgs