Speicherverwaltung
Nach oben zu Speicherverwaltung - Index
In diesem Hilfethema werden die beiden Speichermanager beschrieben, die auf den verschiedenen Zielplattformen verwendet werden. Außerdem finden Sie hier eine kurze Erläuterung der Speicheranforderungen von Variablen.
Inhaltsverzeichnis
Standard-Speichermanager
Der verwendete Speichermanager wird von der Zielplattform/vom Compiler Ihrer Anwendung bestimmt.
In der folgenden Tabelle ist der Standard-Speichermanager für die jeweilige Plattform aufgeführt.
Plattform | Compiler | Name des Speichermanagers |
---|---|---|
Win32 |
FastMM (GETMEM.inc) | |
Win64 |
FastMM (GETMEM.inc) | |
OSX64 |
Posix/64 | |
OSXARM64 |
Posix/64 | |
Linux64 |
Posix/64 | |
iOSDevice64 |
Posix/64 | |
iOSSimARM64 |
Posix/64 | |
Android |
Posix/32 | |
Android64 |
Posix/64 |
Der FastMM-Speichermanager (Win32 und Win64)
Der Speichermanager verwaltet alle dynamischen Speicherzuweisungen und -freigaben in einer Anwendung. Die Standard-System-Prozeduren New, Dispose, GetMem, ReallocMem und FreeMem verwenden diesen Speichermanager. Alle Objekte, dynamischen Arrays und langen Strings werden vom Speichermanager zugewiesen.
Für Win32 und Win64 ist der Standard-FastMM-Speichermanager speziell auf Anwendungen zugeschnitten, die sehr viele Blöcke kleiner bis mittlerer Größe belegen. Dies ist typisch für objektorientierte Anwendungen und für Anwendungen, die String-Daten verarbeiten. Der Speichermanager ist für eine effiziente Ausführung (hohe Geschwindigkeit und wenig Speicher-Overhead) in Einzel- und Multi-Thread-Anwendungen optimiert. Andere Speichermanager, wie die Implementierungen von GlobalAlloc, LocalAlloc und die Unterstützung des privaten Heap in Windows, sind in solchen Situationen weniger geeignet und verlangsamen eine Anwendung, wenn sie direkt verwendet werden.
Um die bestmögliche Leistung zu erzielen, arbeitet der Speichermanager direkt mit der API für virtuellen Speicher zusammen (über die Funktionen VirtualAlloc und VirtualFree).
Unter Win32 unterstützt der Speichermanager einen Adressraum für den Benutzermodus von bis zu 2 GB.
Hinweis: Im Thema Vergrößern des Speicheradressraums finden Sie Informationen zur Vergrößerung des Adressraums für den Benutzermodus auf 3 GB.
Die Blöcke des Speichermanagers werden auf ein Vielfaches von 4 Byte aufgerundet und enthalten einen 4 Byte großen Header, in dem die Größe des Blocks und weitere Statusbits gespeichert sind. Die Startadresse der Blöke ist daher mindestens an 8-Byte-Grenzen oder optional an 16-Byte-Grenzen ausgerichtet, was eine optimale Geschwindigkeit bei ihrer Adressierung gewährleistet. (Siehe System.SetMinimumBlockAlignment)
Unter Win64 unterstützt der Speichermanager einen Adressraum für den Benutzermodus von bis zu 16 EiB.
Hinweis: Die tatsächliche, maximal zuweisbare Größe ist von der CPU-Implementierung und dem Betriebssystem abhängig. Beispielsweise unterstützt die aktuelle Intel/X64-Implementierung bis zu 256 TiB (48 Bit), und Windows 7 Professional unterstützt bis zu 192 GiB.
Die Blöcke des Speichermanagers werden auf ein Vielfaches von 16 Byte aufgerundet und enthalten einen 8 Byte großen Header, in dem die Größe des Blocks und weitere Statusbits gespeichert sind. Die Startadresse von Speicherblöcken wird mindestens an 16-Byte-Grenzen ausgerichtet.
Unter Win32 und Win64 wendet der Speichermanager einen Algorithmus an, der künftige Neuzuweisungen von Blöcken antizipiert. Dadurch wird die Verringerung der Ausführungsgeschwindigkeit aufgehoben, die in der Regel mit solchen Operationen einhergeht. Dieser Zuweisungsalgorithmus vermindert auch die Adressraumfragmentierung. Der Speichermanager stellt einen Mechanismus für die gemeinsame Nutzung bereit, für den keine externe DLL erforderlich ist.
Der Speichermanager enthält Berichtsfunktionen, die Anwendungen dabei unterstützen, ihre eigene Speicherverwendung und potenzielle Speicherlecks zu überwachen.
Der Speichermanager stellt die beiden Prozeduren GetMemoryManagerState und GetMemoryMap bereit, über die Anwendungen Informationen über den Status des Speichermanagers und ein detailliertes Abbild der Speicherverwendung abrufen können.
Der Posix-Speichermanager (Posix-Plattformen)
Der Posix-Speichermanager wird für die Zielplattformen/Compiler macOS 64 Bit, macOS ARM 64 Bit, Linux 64 Bit, iOS-Gerät 64 Bit, iOS-Simulator ARM 64 Bit, Android 32 Bit oder Android 64 Bit verwendet.
Alle Speicherverwaltungsfunktionen und -methoden verwenden die Posix-Systembibliothek, wie in der folgenden Tabelle gezeigt:
RTL | POSIX-Funktion |
---|---|
Variablen
Globale Variablen werden im Datensegment der Anwendung zugewiesen und bleiben bis zur Beendigung des Programms erhalten. Lokale Variablen, die innerhalb von Prozeduren und Funktionen deklariert sind, werden auf dem Stack der Anwendung abgelegt. Wenn eine Prozedur oder Funktion aufgerufen wird, reserviert sie auf dem Stack Speicherplatz für ihre lokalen Variablen. Bei der Beendigung der Prozedur oder Funktion werden die lokalen Variablen wieder freigegeben. Variablen können aber aufgrund von Optimierungsaktionen des Compilers auch zu einem früheren Zeitpunkt freigegeben werden.
Unter Win32 wird der Stack einer Anwendung durch zwei Werte definiert: die Mindestgröße und die Maximalgröße. Diese Werte werden über die Compiler-Direktiven $MINSTACKSIZE und $MAXSTACKSIZE gesteuert. Die Voreinstellung lautet 16.384 (16 KB) bzw. 1.048.576 (1 MB). Einer Anwendung steht nie weniger Stack als die Mindestgröße und nie mehr Stack als die Maximalgröße zur Verfügung. Wenn einer Anwendung weniger Speicher zur Verfügung steht, als es der Wert für die Mindestgröße des Stack vorschreibt, gibt Windows beim Start der Anwendung eine entsprechende Fehlermeldung aus.
Wenn eine Win32-Anwendung mehr Stack benötigt als die angegebene Mindestgröße, wird ihr in Blöcken von 4 KB automatisch weiterer Speicher zugewiesen. Schlägt die Zuweisung fehl, weil kein weiterer Speicher vorhanden ist oder die Maximalgröße des Stacks überschritten würde, wird eine EStackOverflow-Exception ausgelöst. (Die Stack-Überlaufprüfung wird automatisch durchgeführt. Die Compiler-Direktive $S zum Ein- und Ausschalten dieser Prüfung wurde aber aus Gründen der Abwärtskompatibilität beibehalten.)
Der Speicher für dynamische Variablen, die Sie mit den Prozeduren GetMem oder New erzeugen, wird auf dem Heap reserviert. Die Variablen bleiben bis zu einem entsprechenden FreeMem- bzw. Dispose-Aufruf erhalten.
Lange Strings, WideStrings, dynamische Arrays, Varianten und Interfaces werden auf dem Heap zugewiesen. Ihr Speicher wird aber dennoch automatisch verwaltet.