Gibt es im Arbeitsspeicher eigentlich so etwas wie Speicherfragmentierung?
-
Wenn sich mehrere Anwendungen den Hauptspeicher teilen müssen und der vielleicht 2 GB groß ist und nun nur noch 2 Lücken mit jeweils 50 MB frei sind und eines der Anwendungen (1 Prozess) nun weitere 90 MB reservieren will, kann es dann diese 2 Lücken reservieren oder muß der Speicher vom OS umgeschichtet werden?
Wenn ja, wie wird dann für die Anwendung der Speicher als zusammenhängendes verituelles Stück vorgeaukelt?
Mit einem ersten und zweiten Limit und Basis-Paars ist es hier ja nicht getan,
wenn das erste Paar für das Programm und das zweite für den Benutzer reserviert ist und nun das Progrmam eigentlich noch ein 3. und 4. Paar für die obige 90 MB benötigt.Wie wird das also technisch umgesetzt?
-
Arbeitsspeicher ist hochfragmentiert, interessiert aber keinen. Bei Festplatten kann es zu einem Performanceproblem kommen, was aber an der technischen Umsetzung liegt: Es gibt einen beweglichen Lesekopf, der bei starker Fragmentierung oft seine Position ändern muss, das benötigt Zeit.
Arbeitsspeicher wird generell in 4kb-Blöcken verwaltet, den sogenannten "Pages", das gesamte Verfahren nennt sich dementsprechend "Paging". Für dein Problem bedeutet das im wesentlichen: Die Anwendung kann den gesamten Restspeicher bekommen, wenn sie mag - umgeschichtet wird dabei nichts. Der Arbeitsspeicher verhält sich wie ein einzelner Block, alles völlig transparent für dich. Umschichtungen finden nur statt, wenn das Betriebssystem Daten zwischen Auslagerungsdatei aka Swap und Arbeitsspeicher austauscht.
-
Arbeitsspeicher wird generell in 4kb-Blöcken verwaltet
Doch nicht generell. lol.
-
falls man nicht mit sehr kleinen pages arbeitet und dauernt vielfaches der page-size ueber das OS allokiert, kann speicher sehr stark fragmentieren und ziemlich viel probleme bereiten.
Dann bedarf es verschiedener strategieen um das zu limitieren, aber es gibt keine gute loesung im generellen.Ueber as OS zu allokieren mindert speicher fragmentierung wenn du im bereich der pages allokierst, allokierst du z.b. viele kleine strings und dein OS hat 1MB pages, wirst du recht viele luecken haben im normalfall.
Als optimierung gibt es dann verschiedene allokierungs strategieen (bestfit, worstfit um mal zwei zu nennen), dazu splitting strategieen. Es gibt spezielle verwaltungs strategieen (z.b. bucket allokatoren, pools).
dann gibt es ram defragmentierungen, das passiert bei z.b. .Net und JVM automatisch, bei anderen sprachen wie z.b. c++ muss man den code entsprechend anpassen.
wenn es garnicht anders geht, muss man per hand alle allokationen instrumentieren um ihnen ihren speziellen heap mit individueller verwaltungsstrategie zu geben.
das problem mit fragmentation ist nicht so sehr die performance als eher die ausbeute. ohne was zu machen kann man im normalfall (meiner erfahrung nach, und ich beschaeftige mich damit recht intensiv
) von ca 30% brachligendem speicher ausgehen wenn man dann out-of-mem ist bei einer allokation (wegen der groesse oder alignment restriktionen). Mein bester memory manager kommt zZ auf ca 97% bis 98% ausnutzung bis es trotz eigentlich vorhandenem speicher keine allokation gibt, im real world test.
wenn man sowas optimieren will, muss man (Fast schon mehr als bei performance) sehr genau profilen was passiert. Manchmal hat man 256MB und nur 4000 allokationen, mit vielleicht 20/s. manchmal 512kB und 60000 allokationen bei 200k/s.
etc.
-
Mich würde generell interessieren, woher ihr das wissen erlangt?
Uni? Wiki? Arbeit?
-
Interessiert0r schrieb:
Mich würde generell interessieren, woher ihr das wissen erlangt?
Uni? Wiki? Arbeit?Es gibt so kommische Dinger, die nennen sich Bücher. Google einfach mal danach
-
Und in welchen Büchern steht das drin bzw. welche sind empfehlenenswert?
-
"Operating System Concepts", Silberschatz
ist da glaube ich nen Klassiker
-
oder "Moderne Betriebssysteme" von Tanenbaum
-
Da ich sowas schon selbst mit C++ und Smart Pointern programmiert habe:
Garbage Collections wie bei Java und .NET verwalten den Speicher i.d.R. so geschickt, dass die Fragmentierung sehr gering ist. Dazu gibt es spezielle Algorithmen à la Mark and Compact. Das bedeutet konkret, dass man nicht mehr gebrauchte Blöcke im Speicher freigibt (Mark and Sweep) und in einem zweiten Schritt die Blöcke, die noch in Verwendung sind, umschichtet (Erweiterung zu Mark and Compact).
Die bei der Freigabe von Blöcken entstandenen Löcher werden so möglichst effizient wieder gestopft; im Gegenzug werden die hinteren Speicherbereiche wieder frei und die Fragmentierung nimmt ab. Wichtig ist hier, dass man in den meisten Fällen keine nackten Zeiger mehr verwenden darf, da alle Zeiger, die auf einen zu verschiebenden Speicherblock zeigen, geändert werden müssen, da sich ja z.B. die Adressen von Objekten zur Laufzeit ändern können, ohne dass sich der Programmierer darum kümmern muss.
Dieser ganze Mechanismus wird dann noch mit Optimierungen wie Generations und Dirty Flags kombiniert, damit der Aufwand für die Verwaltung des Speichers nicht zu gross wird. Dabei werden die Speicherblöcke kategorisiert nach diversen Kriterien, unter anderem danach, wie lange diese am Leben bleiben. Das heisst, dass man Speicherblöcke, die kurzlebige Objekte enthalten, anders behandelt als diejenigen, welche über Stunden unangetastet bleiben.
Zu diesem Thema kann man definitiv ganze Bücher schreiben. Ich selbst habe nur eine 30-seitige Arbeit geschrieben, welche dieses Thema am Rande anschneidet (Hauptthema war etwas völlig anderes^^ die super Bewertung kommt wohl daher, dass niemand, auch nicht der Dozent, überhaupt verstanden hat, wie es funktioniert
)
MfG