Fragen zum Zusammenspiel zwischen malloc und OS
-
Hallo,
ich habe zuletzt meine erste größere Programmieraufgabe erledigt und hatte dann auf der größten Testinstanz die Prämiere in Sachen malloc-Fehlschlag (NULL). Ich frage mich jetzt zwei Sachen:
- Das ist jetzt kein hartes Faktenwissen, aber ich hatte immer fest gedacht, dass das Betriebssystem bestimmte Mechanismen nutzt (Paging, Swapping, ...), um selbst bei ausgelastetem Arbeitsspeicher durch Hin-und Herschieben der Daten einen größeren Arbeitsspeicher zu simulieren. Nun war es so, dass ich die Speicherauslastung im Windows-Taskmanager verfolgt und festgestellt habe, dass malloc eben direkt fehlschlug, als der Arbeitsspeicher voll war.
Benutzt malloc solche Mechanismen nicht (bzw. sind es ja Mechanismen vom OS, die aber hier scheinbar nicht greifen) und wenn nicht, warum nicht?
- Angenommen, ich alloziiere n*sizeof(x). Ist es dann wirklich so, dass ich n*sizeof(x) physikalisch benachbarte Speicherblöcke bekomme oder sind diese nur auf irgendeiner Adressierungsebene benachbart?
Angenommen, es gibt kein n*sizeof(x) großes freies Speicherstück, aber insgesamt noch genügend freien Speicher. Wird dann eine Defragmentierung veranlasst oder gibt es einfach einen Fehlschlag?
Ich bin mir bewusst, dass ich grade in diesem Speicherverwaltungssektor vom Betriebssystem wirklich mehr Halbwissen als Wissen habe, aber ich verstehe gerade das Zusammenspiel von malloc und den Mechanismen des OS nicht. Es wäre ganz cool, da ein bisschen Aufklärung (evtl. auch in Form guter Links) zu erhalten.
Vielen Dank und freundliche Grüße,
plizzz
-
Hallo,
natürlich muß malloc das OS fragen. Also greifen auch alle Mechanismen des BS.
Alle Betriebssysteme mit virtuellem Speicher sollten auch mit fragmentiertem Arbeistspeicher bzw. Auslagerungsdatei kein Problem haben, da der Addressraum eh nur virtuell ist.
Wenn die Auslagerungsdatei voll ist und auch nicht vergrößert werden kann, dann gibt malloc einen NULL-Pointer zurück.
Es kann aber auch andere Gründe geben. Zum Beispiel ist der Adressraum auf 32-Bitsystemen pro Anwendung auf 2GB begrenzt.
mfg Martin
-
plizzz schrieb:
- Angenommen, ich alloziiere n*sizeof(x). Ist es dann wirklich so, dass ich n*sizeof(x) physikalisch benachbarte Speicherblöcke bekomme oder sind diese nur auf irgendeiner Adressierungsebene benachbart?
Du bekommst einen in deinem Adressraum zusammenhängenden Speicherblock. Macht ja gar keinen Sinn, das auch für physikalische Adressen zu fordern.
Angenommen, es gibt kein n*sizeof(x) großes freies Speicherstück, aber insgesamt noch genügend freien Speicher. Wird dann eine Defragmentierung veranlasst oder gibt es einfach einen Fehlschlag?
Dann gibt es einen Fehlschlag. Ich weiß nicht, wie du dir eine Defragmentierung vorstellst. Dazu müsste man ja alle Pointer identifizieren und ggf. abändern, so dass sie auf den neuen Bereich zeigen. Das ist in einer Lowlevel-Sprache wie C gar nicht möglich. In Sprachen mit Garbage Collection sieht das eventuell anders aus.
-
Hallo plizzz,
malloc kann auch fehlschlagen,
wenn nicht genügend virtueller Speicher zur Verfügung steht.
Wenn der angeforderte Block nicht mehr am Stück virtuell zur Verfügung steht,
liefert malloc auch null.Anders beim realen Speicher,
hier kann nahezu beliebig Pageweise verschoben geswapped, ... gemacht werden.
Übrigends ist SWAP kein virtueller Speicher,
das ist ganz realer (langsamer) Speicher.Hmm ist schon blöd, wenn man noch realen Speicher hat und
einem der virtuelle Speicher ausgeht...
Ich vermute hier auch Defragmentierung des virtuellen Speichers.
z.B. Es wird zu oft temporär Speicher unterschiedlicher Größe angefordert und
wieder freigeben, so das viele (kleine) Lücken im virtuellen Adressraum enstehen.
Die einmal herausgeben Adressen des virtuellen Speichers lassen sich ja nicht ändern.
Wird nun ein größerer Block angefordert passt er in keine der Lücken mehr rein.
Oder es wurde einfach zu viel alloziert, oder oder oder ...Jedenfalls macht es Sinn die Speicherverwendung mal zu analysieren.
Man kann - glaub - malloc und free überschreiben.Ich habe z.B. eine (selbst geschriebene) lib mit extra makros
die ich verwenden muss. Damit kann ich malloc und free hooken
und erhalte statistik, ...Es gibt auch tools extra dafür,
habe ich aber noch nicht verwendet ...Viel Erfolg,
Gruß Frank
-
Ok danke, also arbeitet malloc dann wohl mit dem virtuellen Speicher, der vom OS zur Verfügung gestellt wird und überlasst ansonsten dessen Verwaltung dem OS, wenn ich das richtig verstanden habe. Ich werde nochmal überprüfen, wie sich der Speicher bei Ausführung des Programms verhält und dabei evtl. etwas mit der Auslagerungsdatei rumtesten.
-
plizzz schrieb:
Ok danke, also arbeitet malloc dann wohl mit dem virtuellen Speicher, der vom OS zur Verfügung gestellt wird und überlasst ansonsten dessen Verwaltung dem OS, wenn ich das richtig verstanden habe. Ich werde nochmal überprüfen, wie sich der Speicher bei Ausführung des Programms verhält und dabei evtl. etwas mit der Auslagerungsdatei rumtesten.
Fast.
Mußt Dich von dem Gedanken trennen, ein Coder, eine Maschine und ein malloc, wenn ein OS mit im Spiel ist, weil da schon etliche defaults ins Spiel kommen, von denen Du meist nie was zu spüren bekommst. Malloc() ist eher ein Mikrotom, um sich den Speicher in kleineren Scheibchen runterzusägen. Für massivere Sachen geht man über das Filesystem oder bezieht Speicher über OS- Calls, letztere natürlich nicht portabel.Mach' mal ein Gedankenexperiment (oder programmier's nach):
Du beziehst Speicher für int stückchenweise per malloc() und wenn der Speicher voll ist, free()st Du jedes zweite Element. Jetzt sollte die Hälfte frei sein, aber Du kriegst nichtmal mehr den Platz für'n Buffer. Der Speicher bleibt fragmentiert, es gibt gar keine Garbage Collection.Abhilfe: Beim Speicherfüllen und Abräumen sowas vermeiden oder Smartheaps (also externe Libs) einsetzen: Die schnappen sich meist im Startup an Heap, was da ist und verwalten den über malloc/realloc/free- Ersatzaufrufe. Zusätzlich gibt's dazu Defragmentierfunktionen.
Ich hab' nur so'n Ding noch nie wirklich gebraucht ...
-
Ok, nochmal zur Sicherheit, ob ich es richtig verstehe: Wenn Speicher defragmentiert wird, dann wird physikalisch auf der Disk gar nichts verändert, sondern nur der logische Adressraum umgestrickt. Stimmt das?
-
plizzz schrieb:
Ok, nochmal zur Sicherheit, ob ich es richtig verstehe: Wenn Speicher defragmentiert wird, dann wird physikalisch auf der Disk gar nichts verändert, sondern nur der logische Adressraum umgestrickt. Stimmt das?
Posten wir in Chinesisch? Oder liest Du nicht, was da steht?
Es wird NICHT defragmentiert, zumindest nicht in C. Und das mit der Disk taucht hier das erste mal auf, was auch immer das mit der Frage zu tun haben soll ...
-
plizzz schrieb:
Ok, nochmal zur Sicherheit, ob ich es richtig verstehe: Wenn Speicher defragmentiert wird, dann wird physikalisch auf der Disk gar nichts verändert, sondern nur der logische Adressraum umgestrickt. Stimmt das?
Wenn der Entwickler des OS nicht gehirnamputiert ist, wirst Du wohl recht haben. Abert das ist Sache des OS. Aus der Sicht des C/C++ Entwicklers spielt das keine Rolle, für den ist nur der logische Adressraum von Bedeutung. Und da weder C++ noch C irgendwelche Mechanismen zur Defragmentierung des logischen Speichers anbieten, brauchst Du Dir darüber erst recht keine Gedanken zu machen.
mfg Martin
-
Ich habe doch verstanden, dass C keine Defragmentierung des Speichers veranlasst. Daher hat das wirklich nicht so viel mit der Ausgangsfrage zu tun, aber ich nahm einfach mal an, dass ihr dazu trotzdem ein wenig wisst und hab dann einfach mal gefragt.