Warum überlastet Linux standardmäßig den Speicher?

Warum überlastet Linux standardmäßig den Speicher?

Bezogen auf die SuperUser-Frage unterhttps://superuser.com/questions/200387/linux-overcommit-memoryMeine Frage lautet: Aus welchem ​​Grund wurde Überbelegung als Standard zugelassen?

Seit 2.5.30 lauten die Werte: 0 (Standard): wie zuvor: ungefähr schätzen, wie viel Überbelegung sinnvoll ist,

Antwort1

Die Notwendigkeit, Speicher unter Linux (und in Unix-Systemen insgesamt) übermäßig zuzuweisen, ergibt sich zu einem großen Teil aus der Notwendigkeit, den fork()Systemaufruf zu implementieren, der den Adressraum des aufrufenden Prozesses dupliziert.

In den meisten Fällen folgt auf diesen Systemaufruf ein . exec()Diese Kombination führt dazu, dass ein separates Programm als untergeordnetes Programm des aktuellen Prozesses erstellt wird. In diesem Fall wird der größte Teil des duplizierten Adressraums letztendlich nicht verwendet.

Um dies effizient zu gestalten, verwendet Linux Copy-on-Write, um eine Duplizierung des Speichers der aufrufenden Anwendung zu vermeiden fork(). Auf diese Weise kann vermieden werden, dass alle Seiten kopiert werden müssen, nur um sie kurz nach exec()dem Aufruf zu verwerfen.

Aber zum Zeitpunkt fork()des Aufrufs gibt es keine Möglichkeit zu erkennen, ob ein exec()kommt. Es ist durchaus möglich, dass dies verwendet wird, um Worker-Kinder zu erzeugen, und dass die Wiederverwendung des Adressraums des übergeordneten Elements erwünscht ist. (Diese Technik war bei Daemons, die vorgegabelte Worker zur Handhabung von Verbindungen verwendeten, recht beliebt.) In diesem Fall wird der Großteil oder zumindest ein Teil des Speicherbedarfs für ein gegabeltes Kind vorhanden sein (vielleicht nicht 100 % des Speichers des übergeordneten Elements, aber man könnte den Großteil davon annehmen).

fork()Aber für diesen Fall immer Speicher zu reservieren, ist für den + -Fall problematisch exec(), insbesondere wenn der übergeordnete Prozess ein lang laufender Prozess ist, der mehrere Gigabyte Speicher reserviert und viele untergeordnete Prozesse aufspaltet. Wenn es keine Überbelegung gäbe, müssten Sie einen Betrag reservieren, der den vielen Gigabyte entspricht, die der übergeordnete Prozess verwendet, und zwar für jeden aufgespaltenen untergeordneten Prozess. Aber nichts (oder fast nichts) davon würde wirklich verwendet werden, da exec()diese Reservierung sofort gelöscht würde. Das Endergebnis ist, dass eine solche Arbeitslast entweder eine riesige Menge an Swap-Speicherplatz erfordern würde (um mit den Reservierungen fertig zu werden, wäre das meiste davon ungenutzt, müsste aber für den schlimmsten Fall vorhanden sein) oder etwas wie Überbelegung.

Obwohl fork()dies eine gute Illustration dieses Beispiels ist, führen auch andere APIs in Linux/Unix dazu, dass eine Überbelegung erforderlich ist. Wenn beispielsweise malloc()aufgerufen wird (oder genauer gesagt die Systemaufrufe, die es implementieren), wird tatsächlich kein Speicher zugewiesen, bis er vom Prozess „berührt“ wird. Daher ist es völlig in Ordnung, einen sehr großen Gigabyte-Block zuzuweisen und diesen sparsam zu verwenden, sodass tatsächlich nur wenige Megabyte verwendet werden. Die Tatsache, dass diese APIs auf diese Weise funktionieren, bedeutet, dass Programme diese Eigenschaften ausnutzen, was bedeutet, dass sie ohne Überbelegung höchstwahrscheinlich abstürzen würden (es sei denn, Sie haben wirklich viel Speicher oder Swap zu verschwenden, indem Sie diese Reservierungen unterstützen).

Eine interessante Diskussion zu diesem Thema fork()finden Sie unterdieser LWN-Beitrag zu einem Artikel von Microsoft Research. Der Artikel selbst ist natürlich interessant. Aber man sieht, wie die Kommentare sofort auf Überforderung und die damit verbundenen Probleme eingehen.

Der Artikel trägt den NamenEine Weggabelung.

Antwort2

Ich denke, der Grund liegt darin, dass nicht alle Leute über genügend Ressourcen verfügen, um Speicher zu kaufen. In solchen Fällen sollten daher alle Anwendungen ordnungsgemäß ausgeführt werden. Es hilft, Anwendungen mit geringen Ressourcen auszuführen.

verwandte Informationen