On Fri, Feb 23, 2001 at 09:36:06AM +0100, Eric Schaefer wrote:
On Fri, Feb 23, 2001 at 01:01:33AM +0100, Reinhard Foerster wrote:
- du sorgst dafür, dass es zu diesen Speicherengpässen nur sehr, sehr, sehr, ... selten kommt. (das bedeutet: ohne Böswilligkeit eines Nutzers im praktischen Betrieb nie)
Eine Möglichkeit: "Swapspace ist billig" (S.R. 1998) :-)
Ja, so machen die Unixe das alle. Wenn du aber 128 MB ram hast und 512 MB swap gibt Linux den momentan freien Speicher trotzdem *BELIEBIG OFT HERAUS*
D.h. du kannst 100 Prozesse laufen lassen und in allen ein erfolgreiches malloc(600 MB) machen. Das Übel ist ganz einfach zu erkären: Linux markiert eine Seite nicht als belegt, wenn der Kern die Seite an einen Prozess herausgibt sondern erst, wenn der Prozess sie auch nutzt. Somit kannst du immmer wieder freiesRAM+FreienSwap anfordern. Wird der Speicher dann genutzt, kann die Kiste logischwerweise nichts anderes machen als irgendwas killen. Man mag es kaum glauben, aber es ist im Linux wirklich so "gelöst". In einem anderen Posting habe ich eine kleines Programm geschickt, dass das Verhalten demonstiert. Hoffentlich ist das in 2.4 anders.
- funktioniert super, verursacht aber einige Probleme an anderen
Stellen :) 2. machen alle anderen mir bekannten Unixe außer Linux sehr erfolgreich (ich meine hier Linux bis v2.2, zu v2.4 kann ich mich mangels Ahnung nicht äußern)
Wie tun die das? Nur solange Pages ausgeben, wie auch tatsächlich welche das sind? Wenn ja, warum dann "sehr, sehr, sehr selten" und nicht "nie"?
Weil es die automatisch allokierten Sachen gibt, also vor allem den Stack. Angenommen du machst:
int addiere(int a, int b) { if (b == 0 ) return a; else return addiere(a+1, b-1) }
Also rekursiv addieren. Hier hat der Programmierer keine Stelle, wo er abfragt, ob noch Speicher da ist und ggf. reagieren kann und benötigt u.U. nahezu unendlich viel Speicher. Das System kann aber nur eine gewisse Größe für die Stacks aller Prozesse vorhalten und bei überschreiten des Limits den Prozess abschiessen. Bei der Variante ist es aber sehr einfach für den Kern, wirklich den Prozess zu killen, der so viel Stack haben wollte. Das ist also recht unkritisch. Wenn du die Stackbereiche aller Prozesse schon von Anfang an als belegt rechnest, bist du schon ziemlich auf der sicheren Seite, verschwendest aber in 99% der Fälle massig RAM oder Swap. Stell dir vor, du willst absichern, dass addiere(1Mrd, 2Mrd) jederzeit funktioniert. Das ist praktisch nicht machbar, da du mehrere GB reservieren müsstest und das so oft, wie die Prozesstabelle maximal Einträge hat. Deshalb musst du bei der Reservierung von Stack-Speicher ein Kompromiss eingehen und der Speicher wird u.U. doch knapp. Im praktischen Betrieb passiert das jedoch nahezu nie.
Leider ist auch das nicht so einfach:
- Prozessorlast: Dann kann man kein "make" mehr eingeben.
Muß schon ein tollen Makefile sein, damit make selbst echte Last erzeugt.
Das habe ich an der Stelle auch gedacht :)
Reinhard