Memory allocation in a Delphi Application
Memory in a Delphi Application
When we run our Delphi Application it acquires some memory to store variables, constants, parameters that we have used. And during runtime several times we create and free objects in our application so accordingly memory is occupied and freed. And those freed memories can be used to store other values. So how those memories are managed by a Delphi application, we will see in this blog.
So at first what memory is? in short, computer memories are row of bytes. One could also say a byte is the smallest addressable piece of memory. A byte is a small storage unit that can contain 256 separate values (0 up to 255). In current 32 bit Delphi, memory can be seen as an array of maximum 2 gigabytes in size (231 bytes). The index of a byte in this huge array is called its address. What these bytes contain, depends on how they are used like the value of 97 can mean a byte of value 97, as well as the character 'a'. If you combine more than one byte, you can store much larger values. In 2 bytes you can store 256*256 different values, etc. The bytes in memory can be addressed by numbering them, starting at 0, and up to 2147483647 assuming we have 2 gigabyte — and even if we don’t have then Windows will try to make it look if we have added with our computer.
How Delphi Application allocates memory to Variables, Constants, Parameters or etc...
Local variables:
Normal typed variables
procedure Test;
var
MyVar: Integer;
A local variable exists on the stack. This is a piece of memory that is used for housekeeping. It contains the parameters for the function, the return address, so the CPU knows where to return if the program has ended and the local variables used in the functions. Local variables only exists during the lifetime of a function. If the function is ended, you can't access the local variable in a reliable way. And when we don't have much free area in Stack to store values we get EStackOverflow error.
Class Object typed variables
procedure Test2;
var
MyClass: TMyClass;
begin
MyClass := TMyClass.Create;
The variable MyClass is a pointer which is a local variable that is defined on the stack. By constructing an object you allocate a piece of memory on the heap the large piece of 'other' memory that is not used for programs and stacks. The variable MyClass contains the address of this piece of memory. Heap variables exist until you release them. That means that if you exit the function Test2 without freeing the object, the object still exists on the heap. But you won't be able to access it because the address (variable MyClass) is gone.
Global variables:
unit X;
interface
var
MyVar: Integer;
A global variable is defined in the datasegment. The datasegment is fixed. And during the lifetime of the program these variables are available Which means the memory can not be used for other uses. The memory for global variables are reserved by application when the program starts and remains allocated until program terminates.
What is Stack and Heap?
On above we came through that Delphi application stores local variables in Stack or Heap, then what is Stack and Heap. Stack and heap is memory that we allocate dynamically when we create a variable for a function, when we create an instance of a class, when we send parameters to a function and use/pass its result value.
Stack
When we declare a variable inside a function, the memory required to hold the variable is allocated from the stack. We simply write "var x : integer", use "x" in your function, and when the function exits, we do not care about memory allocation nor freeing. When the variable goes out of scope or code exits the function, the memory which was taken on the stack is freed. The stack memory is allocated dynamically using the LIFO "last in first out" approach. In Delphi programs, stack memory is used by Local routine (method, procedure, function) variables, Routine parameters and return types, Windows API function calls and Records. The memory is automatically allocated when we declare a local variable to a function and freed when the function exits.
Heap
Heap is generally used to store Class Object type variables or dynamically created variables like array. When you create an instance of a class, the memory is allocated from the heap. In Delphi programs, heap memory is used when Creating an instance of a class, Creating and resizing dynamic arrays or variants. Memory allocation from the heap is random thus heap operations are a bit slower than those on the stack.
Delphi "Out of Memory" error and why we get?
Sometime in Delphi we get "Out of Memory" error yet if we have enough memory when we check in TaskManager. So why we get this error, the reason is even though we have lots of free memory in total, we don’t have any single piece big enough when we try to allocate and application raises an "Out of Memory" exception and quits.
Lets look an example.
Consider we have here ten big units free memory which starts with empty.
1.* are marked as empty memory units
**********
2.Then we make some allocation
AA********
3. and another allocation
AABB******
3. and some more allocation
AABBCDEF**
4. Then we freed 4 units from occupied are
**BB*D*F**
Now suppose we want to allocate three units and we have 6 free memory units. 3 < 6, so it should work.
But there is no single contiguous space in your memory that allows you to allocate 3 units. That's why it will result "Out of Memory" error.
so what is the solution when i need 3 and i have 6 free but not 3 contignous ?
ReplyDelete