Efficient memory management is vital for high-performance applications. Object Pascal simplifies this by managing most object lifecycle details automatically, but developers must understand the underlying principles, especially when using low-level features.
1. Stack vs. Heap Memory
Memory used by your program is divided into key areas:
| Memory Area | Description | Lifespan and Management |
| Stack | Used for storing local variables (simple types like Integer, Boolean, and record types) and function/procedure call frames. | Fast and automatic. Memory is automatically allocated when the routine starts and freed immediately when the routine exits. |
| Heap | Used for storing objects (class instances like TForm, TList) and dynamic arrays. | Slower and requires management. Memory must be explicitly allocated (via Create) and deallocated (via Free) or managed by the system (ARC). |
2. Automatic Reference Counting (ARC)
For mobile and next-generation platforms (iOS, Android, Linux, macOS), modern Delphi utilizes Automatic Reference Counting (ARC) for managing class instances.
- How ARC Works: When an object is created, its reference count starts at 1. Every time a new variable references that object, the count increases. When a variable goes out of scope or is set to
nil, the count decreases. - Automatic Deallocation: When the reference count drops to zero, the runtime system automatically calls the object’s destructor (
Destroy) and frees the memory. - Platform Difference:
- Mobile/Cross-Platform (FMX): ARC is enabled by default. Explicitly calling
Object.Freeis often optional but sometimes necessary for timely cleanup. - Windows Desktop (VCL): ARC is disabled for backward compatibility. You must still use the
try...finally...Freepattern (as learned in D2.5) to manually manage memory and prevent leaks.
- Mobile/Cross-Platform (FMX): ARC is enabled by default. Explicitly calling
Rule of Thumb (VCL): If you call
TObject.Create, you are responsible for ensuringTObject.Freeis called. Use thetry...finallyblock to guarantee this.
// VCL (Windows) Manual Memory Management Example:
var
MyList: TStringList; // Needs manual cleanup
begin
MyList := TStringList.Create;
try
// Use the object...
finally
MyList.Free; // Guaranteed destruction
end;
end;
3. Pointers (Low-Level Memory Access)
Pointers are variables that store the memory address of another variable or data structure, allowing direct, low-level access to memory. In modern Delphi, pointers are rarely needed for standard business logic but are essential for low-level tasks, hardware interaction, and interfacing with external DLLs/APIs (see D3.6).
- Syntax:
- Pointer Type: Declared using the caret symbol (
^) before the data type. E.g.,PInteger = ^Integer; - Address Of: Use the
@operator to get the memory address of a variable. - Dereferencing: Use the
^operator after the pointer variable to access the value stored at that address.
- Pointer Type: Declared using the caret symbol (
Example: Using Pointers
// In the var section:
var
A: Integer;
P: ^Integer; // P is a pointer to an Integer
begin
A := 42;
P := @A; // P now holds the memory address of A
// Dereferencing the pointer P (accessing the value at the address)
ShowMessage(IntToStr(P^)); // Displays 42
// Changing the value via the pointer
P^ := 99;
// A is now 99
ShowMessage(IntToStr(A));
end;
4. Dynamic Memory Allocation (New and Dispose)
When working with simple types (not classes) that need heap allocation (e.g., dynamic records or custom data structures), you use the standard Pascal procedures New and Dispose.
New(P): Allocates memory on the heap for the variable pointed to by pointerP.Dispose(P): Frees the memory allocated byNew.
// In the var section:
var
DataPtr: ^TUserInfo; // Pointer to a TUserInfo record (see D1.6)
begin
New(DataPtr); // Allocate memory for the record on the heap
try
DataPtr^.FirstName := 'Rex'; // Access fields via the dereferenced pointer
// ... use the dynamically allocated record ...
finally
Dispose(DataPtr); // Free the allocated memory
end;
end;
Crucial Distinction:
New/Disposeare for non-class types (like records).TObject.Create/TObject.Freeare for class instances.
