PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Verbrauch von virtuellem Adressraum


GloomY
2005-03-05, 13:21:53
Bezüglich 64 Bit CPUs und Betriebssystemen (beziehungsweise der Knappheit der 32 Bit "Kollegen") bin ich gerade am Überlegen, in welchen Situationen mehr virtueller Adressraum verbraucht (belegt) wird, als physischer Speicher genutzt wird. Vielleicht kann mir da mal der eine oder andere auf die Sprünge helfen.

Dass grundsätzlich die Hälfte des virtuellen Adressraums durch den Kernel reserviert ist, ist sowieso klar, jedoch eine grundsätzliche Gegebenheit. Ich wollt's natürlich hier nur der Vollständigkeit halber erwähnen.

Bisher sind mir folgende Situationen eingefallen:
memory mapped I/O (PCI-Geräte, AGP- usw.)
Hier wird virtueller Adressraum für das Adressieren von Speicher(bereichen) von Erweiterungskarten benutzt. Physischer RAM-Speicher wird gar nicht belegt.
memory mapped files
Statt dem üblichen "open(...), read/write, close(...)" mit einer Datei wird ein Adressbereich reserviert, als ob die Daten schon im Speicher liegen würden. Bei Zugriff darauf gibt es einen Page Fault und das OS lädt die Datei in diesen Speicherbereich hinein. Hier wird zwar physikalischer Speicher verbraucht, aber nur soviel, wie Bereiche der Datei genutzt werden. Im Extremfall wird alles genutzt, dann ist der Verbrauch von virtuellem Adressraum gleich groß wie die Belegung von physikalischem Speicher. Im Schnitt dürfte das aber besonders bei größeren Files nicht der Fall sein, so dass effektiv mehr virtueller Adressraum als physikalischer Speicher belegt wird.
... (to be continued)


Wie sieht das bei dynamisch gelinkten Libraries aus? Da hab' ich noch nicht so ganz den Überblick, weil die doch auch erst zur Laufzeit geladen (=Belegung von physischem Speicher) werden. Wenn diese nicht genutzt würden, dann hätte man ja auch umsonst Adressraum belegt, ohne physischen Speicher zu belegen, oder?

Trap
2005-03-05, 22:45:27
Jeder Prozess hat in einem modernen Betriebssystem einen eigenen virtuellen Adressbereich. DLLs werden sicher in den virtuellen Adressraum jedes Prozess gemapped.

Wenn man eine Anwendung hat die viele Instanzen von sich forked aber ein großer Teil der Speicherseiten nur gelesen wird hat man auch mehr virtuellen Adressraum als physischen Speicher belegt.

Coda
2005-03-05, 23:39:28
Speicherfragmentierung


Dass grundsätzlich die Hälfte des virtuellen Adressraums durch den Kernel reserviert ist, ist sowieso klarSo klar ist das nicht. Es gibt zumindest unter Linux und NT die möglichkeit auf 3 oder sogar 3,5GB Userspace Speicher umzuschalten.

Wenn diese nicht genutzt würden, dann hätte man ja auch umsonst Adressraum belegt, ohne physischen Speicher zu belegen, oder?Hm nein, der Speicherplatz wird ja erst beim laden verwendet und sonst hat man halt paar Pointer ohne sinnvollen Inhalt im Speicher ;)

zeckensack
2005-03-06, 00:20:00
Wie sieht das bei dynamisch gelinkten Libraries aus? Da hab' ich noch nicht so ganz den Überblick, weil die doch auch erst zur Laufzeit geladen (=Belegung von physischem Speicher) werden. Wenn diese nicht genutzt würden, dann hätte man ja auch umsonst Adressraum belegt, ohne physischen Speicher zu belegen, oder?Die belegen erstmal nur Adressraum. Wenn der geladene Prozess der erste ist, der die DLL braucht, dann natürlich auch physikalischen Speicher.

DLLs und alle anderen ausführbaren Dateiformate werden von Windows mit COPY_ON_WRITE versehen. Dh sie belegen nur einmal physikalischen Speicher, solange alle Kopien identisch sind. Bei Schreibzugriffen gibt's einen Page Fault, und der entsprechende Handler dupliziert die Seite.

Coda
2005-03-06, 00:27:45
Naja wenn ich per LoadLibrary ne DLL lad, dann braucht sie vorher keinen Speicherplatz, das meinte ich.

Matti
2005-03-06, 15:36:48
Unter Windows wird virtueller, aber kein physikalischer Speicher verbraucht, wenn ein Speicherblock allokiert ist, aber noch keine Daten reingeschrieben wurden.

Coda
2005-03-06, 16:01:36
Sicher? Ich dachte das ist nur mit VirtualAlloc mit bestimmten Flags so.

Matti
2005-03-06, 17:32:32
"getmem" von Delphi verhält sich jedenfalls so. Welcher API-Aufruf dahinter steht, weiß ich aber nicht.

GloomY
2005-03-06, 22:37:09
Jeder Prozess hat in einem modernen Betriebssystem einen eigenen virtuellen Adressbereich. DLLs werden sicher in den virtuellen Adressraum jedes Prozess gemapped.

Wenn man eine Anwendung hat die viele Instanzen von sich forked aber ein großer Teil der Speicherseiten nur gelesen wird hat man auch mehr virtuellen Adressraum als physischen Speicher belegt.Kommt drauf an, ob du mit "forken" das Erstellen eines neuen Threads oder eines neuen Prozesses meinst. Bei Unix ist das ja üblicherweise ein neuer Prozess. Dann wird ja auch ein neuer Adressraum erzeugt und in den einzelnen Adressräumen der Prozesse ändert sich nichts im Hinblick auf das Verhältnis von virtuellem Adressraum zu belegtem Arbeitsspeicher.

Speicherfragmentierung
Ja, das ist eine praktische Einschränkung. Wenn man es aber ganz genau nimmt, sind hier die einzelnen Bytes zwischen belegten Daten schon frei, nur sind sie eben in der Praxis nicht nutzbar, da nicht zusammenhängend.
So klar ist das nicht. Es gibt zumindest unter Linux und NT die möglichkeit auf 3 oder sogar 3,5GB Userspace Speicher umzuschalten.Okay, das stimmt natürlich. Ich bin vom üblichen Default-Wert ausgegangen, was aber natürlich nicht immer so sein muss.
Hm nein, der Speicherplatz wird ja erst beim laden verwendet und sonst hat man halt paar Pointer ohne sinnvollen Inhalt im Speicher ;)Das ist die Sicht vom physischen Speichers aus. Aber im virtuellen Adressraum wird - wie Zeckensack geschrieben hat - durchaus Platz dafür reserviert.
Die belegen erstmal nur Adressraum. Wenn der geladene Prozess der erste ist, der die DLL braucht, dann natürlich auch physikalischen Speicher.Okay :)
Weisst du zufällig ob dabei die gesamten DLL in den Speicher geladen oder nur der Teil des Codes, welcher gebraucht wird? (page-weise?)

Ach ja: Danke an Alle für die Antworten. =)