Die Speicherverwaltung unter Linux unterscheidet sich von anderen Systemen. Das Schlüsselprinzip ist, dass ungenutzter Speicher verschwendeter Speicher ist. Linux versucht auf viele Arten, die Speicherauslastung zu maximieren, was (meistens) zu einer besseren Leistung führt.
Es geht nicht darum, dass in Linux "gar nichts funktioniert", sondern dass sein Verhalten etwas anders ist als erwartet.
Wenn Speicherseiten aus der mmapped-Datei geholt werden, muss das Betriebssystem entscheiden, welche physischen Speicherseiten es freigeben (oder auslagern) soll, um sie zu nutzen. Es wird nach Seiten gesucht, die leichter ausgelagert werden können (kein sofortiger Festplattenzugriff erforderlich) und die weniger wahrscheinlich erneut verwendet werden.
Der POSIX-Aufruf madvice() dient dazu, dem System mitzuteilen, wie Ihre Anwendung die Seiten verwenden wird. Aber wie der Name sagt, handelt es sich um einen Rat, damit das Betriebssystem bessere Entscheidungen bei der Umleitung und beim Auslagern von Seiten treffen kann. Es ist weder eine Richtlinie noch ein Befehl.
Um die Auswirkungen von madvice() auf Linux zu demonstrieren, habe ich eine Übung, die ich meinen Schülern gebe, modifiziert. Sehen Sie sich den vollständigen Quellcode hier an. Mein System ist 64-Bit und hat 2 GB RAM, von denen derzeit etwa 50% verwendet werden. Mit dem Programm wird eine 2 GB große Datei gemappt, sequenziell gelesen und alles verworfen. Es wird alle 200 MB gelesenen RSS-Verbrauch gemeldet. Die Ergebnisse ohne madvice():
~% ./madvtest file.dat n
0 : 3 MB
200 : 202 MB
400 : 402 MB
600 : 602 MB
800 : 802 MB
1000 : 1002 MB
1200 : 1066 MB
1400 : 1068 MB
1600 : 1078 MB
1800 : 1113 MB
2000 : 1113 MB
Linux hat Dinge aus dem Speicher gedrängt, bis etwa 1 GB gelesen wurde. Danach begann es, den Prozess selbst zu belasten (da die anderen 50% des Speichers von anderen Prozessen aktiv waren) und stabilisierte sich bis zum Ende der Datei.
Jetzt, mit madvice():
~% ./madvtest file.dat y
0 : 3 MB
200 : 202 MB
400 : 402 MB
600 : 494 MB
800 : 501 MB
1000 : 518 MB
1200 : 530 MB
1400 : 530 MB
1600 : 530 MB
1800 : 595 MB
2000 : 788 MB
Beachten Sie, dass Linux entschieden hat, dem Prozess nur bis zu etwa 500 MB zuzuweisen, wesentlich früher als ohne madvice(). Dies liegt daran, dass die Seiten, die sich bereits im Speicher befinden, wesentlich wertvoller erschienen als die Seiten, die von diesem Prozess als sequenzieller Zugriff markiert wurden. Es gibt einen Schwellenwert im VMM, der festlegt, wann alte Seiten aus dem Prozess entfernt werden sollen.
Sie könnten sich fragen, warum Linux Seiten bis etwa 500 MB zugeordnet hat und nicht viel früher gestoppt hat, da sie als sequenzieller Zugriff markiert wurden. Entweder hatte das System sowieso genügend freie Speicherseiten oder die anderen residenten Seiten waren zu alt, um noch beizubehalten. Zwischen dem Behalten alter Seiten im Speicher, die anscheinend nicht mehr nützlich sind, und dem Bereitstellen neuer Seiten für ein Programm, das gerade läuft, wählt Linux die zweite Option.
Auch wenn sie als sequenzieller Zugriff markiert waren, war es nur ein Rat. Die Anwendung kann immer noch zu diesen Seiten zurückkehren und sie erneut lesen. Oder eine andere Anwendung im System. Der madvice() -Aufruf sagt nur, was die Anwendung selbst tut, Linux berücksichtigt das Gesamtbild.