mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 20:49:19 +02:00
+ Added memory manager section
This commit is contained in:
parent
2d8df61928
commit
8c686201c5
215
docs/prog.tex
215
docs/prog.tex
@ -3253,6 +3253,207 @@ ReleaseTempHeap;
|
|||||||
{All allocated memory is now freed, except for the memory pointed to by 'P' }
|
{All allocated memory is now freed, except for the memory pointed to by 'P' }
|
||||||
...
|
...
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% Debugging the heap
|
||||||
|
\subsection{Debugging the heap}
|
||||||
|
|
||||||
|
\fpc provides a unit that allows you to trace allocation and deallocation
|
||||||
|
of heap memory: \file{heaptrc}.
|
||||||
|
|
||||||
|
If you specify the \var{-gh} switch on the command-line, or if you include
|
||||||
|
\var{heaptrc} as the first unit in your uses clause, the memory manager
|
||||||
|
will trace what is allocated and deallocated, and on exit of your program,
|
||||||
|
a summary will be sent to standard output.
|
||||||
|
|
||||||
|
More information on using the \var{heaptrc} mechanism can be found in the
|
||||||
|
\userref and \unitsref.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% Writing your own memory manager.
|
||||||
|
\subsection{Writing your own memory manager}
|
||||||
|
|
||||||
|
\fpc allows you to write and use your own memory manager. The standard
|
||||||
|
functions \var{GetMem}, \var{FreeMem}, \var{ReallocMem} and \var{Maxavail}
|
||||||
|
use a special record in the system unit to do the actual memory management.
|
||||||
|
The system unit initializes this record with the system unit's own memory
|
||||||
|
manager, but you can read and set this record using the
|
||||||
|
\var{GetMemoryManager} and \var{SetMemoryManager} calls:
|
||||||
|
\begin{verbatim}
|
||||||
|
procedure GetMemoryManager(var MemMgr: TMemoryManager);
|
||||||
|
procedure SetMemoryManager(const MemMgr: TMemoryManager);
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
the \var{TMemoryManager} record is defined as follows:
|
||||||
|
\begin{verbatim}
|
||||||
|
TMemoryManager = record
|
||||||
|
Getmem : Function(Size:Longint):Pointer;
|
||||||
|
Freemem : Function(var p:pointer):Longint;
|
||||||
|
FreememSize : Function(var p:pointer;Size:Longint):Longint;
|
||||||
|
AllocMem : Function(Size:longint):Pointer;
|
||||||
|
ReAllocMem : Function(var p:pointer;Size:longint):Pointer;
|
||||||
|
MemSize : function(p:pointer):Longint;
|
||||||
|
MemAvail : Function:Longint;
|
||||||
|
MaxAvail : Function:Longint;
|
||||||
|
HeapSize : Function:Longint;
|
||||||
|
end;
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
As you can see, the elements of this record are procedural variables.
|
||||||
|
The system unit does nothing but call these various variables when you
|
||||||
|
allocate or deallocate memory.
|
||||||
|
|
||||||
|
Each of these functions corresponds to the corresponding call in the system
|
||||||
|
unit. We'll describe each one of them:
|
||||||
|
\begin{description}
|
||||||
|
\item[Getmem] This function allocates a new block on the heap. The block
|
||||||
|
should be \var{Size} bytes long. The return value is a pointer to the newly
|
||||||
|
allocated block.
|
||||||
|
\item[Freemem] should release a previously allocated block. The pointer
|
||||||
|
\var{P} points to a previously allocated block. The Memory manager should
|
||||||
|
implement a mechanism to determine what the size of the memory block is
|
||||||
|
\footnote{By storing it's size at a negative offset for instance.} The
|
||||||
|
return value is optional, and can be used to return the size of the freed
|
||||||
|
memory.
|
||||||
|
\item[FreememSize] This function should release the memory pointed to by
|
||||||
|
\var{P}. The argument \var{Size} is the expected size of the memory block
|
||||||
|
pointed to by P. This should be disregarded, but can be used to check the
|
||||||
|
behaviour of the program.
|
||||||
|
\item[AllocMem] Is the same as getmem, only the allocated memory should
|
||||||
|
be filled with zeroes before the call returns.
|
||||||
|
\item[ReAllocMem] Should allocate a memory block \var{Size} bytes large,
|
||||||
|
and should fill it with the contents of the memory block pointed to by
|
||||||
|
\var{P}, truncating this to the new size of needed. After that, the memory
|
||||||
|
pointed to by P may be deallocated. The return value is a pointer to the
|
||||||
|
new memory block.
|
||||||
|
\item[MemSize] should return the total amount of memory available for
|
||||||
|
allocation. This function may return zero if the memory manager does not
|
||||||
|
allow to determine this information.
|
||||||
|
\item[MaxAvail] should return the size of the largest block of memory that
|
||||||
|
is still available for allocation. This function may return zero if the
|
||||||
|
memory manager does not allow to determine this information.
|
||||||
|
\item[HeapSize] should return the total size of the heap. This may be zero
|
||||||
|
is the memory manager does not allow to determine this information.
|
||||||
|
\end{description}
|
||||||
|
To implement your own memory manager, it is sufficient to construct such a
|
||||||
|
record and to issue a call to \var{SetMemoryManager}.
|
||||||
|
|
||||||
|
To avoid conflicts with the system memory manager, setting the memory
|
||||||
|
manager should happen as soon as possible in the initialization of your
|
||||||
|
program, i.e. before any call to \var{getmem} is processed.
|
||||||
|
|
||||||
|
This means in practice that the unit implementing the memory manager should
|
||||||
|
be the first in the \var{uses} clause of your program or library, since it
|
||||||
|
will then be initialized before all other units (except of the system unit)
|
||||||
|
|
||||||
|
This also means that it is not possible to use the \file{heaptrc} unit in
|
||||||
|
combination with a custom memory manager, since the \file{heaptrc} unit uses
|
||||||
|
the system memory manager to do all it's allocation. Putting the
|
||||||
|
\file{heaptrc} unit after the unit implementing the memory manager would
|
||||||
|
overwrite the memory manager record installed by the custom memory manager,
|
||||||
|
and vice versa.
|
||||||
|
|
||||||
|
The following unit shows a straightforward implementation of a custom
|
||||||
|
memory manager using the memory manager of the \var{C} library. It is
|
||||||
|
distributed as a package with \fpc.
|
||||||
|
\begin{verbatim}
|
||||||
|
unit cmem;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
Function Malloc (Size : Longint) : Pointer;cdecl;
|
||||||
|
external 'c' name 'malloc';
|
||||||
|
Procedure Free (P : pointer); cdecl; external 'c' name 'free';
|
||||||
|
Procedure FreeMem (P : Pointer); cdecl; external 'c' name 'free';
|
||||||
|
function ReAlloc (P : Pointer; Size : longint) : pointer; cdecl;
|
||||||
|
external 'c' name 'realloc';
|
||||||
|
Function CAlloc (unitSize,UnitCount : Longint) : pointer;cdecl;
|
||||||
|
external 'c' name 'calloc';
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
Function CGetMem (Size : Longint) : Pointer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
result:=Malloc(Size);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CFreeMem (Var P : pointer) : Longint;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Free(P);
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CFreeMemSize(var p:pointer;Size:Longint):Longint;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=CFreeMem(P);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CAllocMem(Size : Longint) : Pointer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=calloc(Size,1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CReAllocMem (var p:pointer;Size:longint):Pointer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=realloc(p,size);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CMemSize (p:pointer): Longint;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CMemAvail : Longint;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CMaxAvail: Longint;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function CHeapSize : Longint;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Const
|
||||||
|
CMemoryManager : TMemoryManager =
|
||||||
|
(
|
||||||
|
GetMem : CGetmem;
|
||||||
|
FreeMem : CFreeMem;
|
||||||
|
FreememSize : CFreememSize;
|
||||||
|
AllocMem : CAllocMem;
|
||||||
|
ReallocMem : CReAllocMem;
|
||||||
|
MemSize : CMemSize;
|
||||||
|
MemAvail : CMemAvail;
|
||||||
|
MaxAvail : MaxAvail;
|
||||||
|
HeapSize : CHeapSize;
|
||||||
|
);
|
||||||
|
|
||||||
|
Var
|
||||||
|
OldMemoryManager : TMemoryManager;
|
||||||
|
|
||||||
|
Initialization
|
||||||
|
GetMemoryManager (OldMemoryManager);
|
||||||
|
SetMemoryManager (CmemoryManager);
|
||||||
|
|
||||||
|
Finalization
|
||||||
|
SetMemoryManager (OldMemoryManager);
|
||||||
|
end.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% Accessing DOS memory under the GO32 extender
|
% Accessing DOS memory under the GO32 extender
|
||||||
@ -3310,6 +3511,8 @@ After using the selector, you must free it again using the
|
|||||||
More information on all this can be found in the \unitsref, the chapter on
|
More information on all this can be found in the \unitsref, the chapter on
|
||||||
the \file{GO32} unit.
|
the \file{GO32} unit.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
% Resource strings
|
% Resource strings
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
@ -4017,7 +4220,7 @@ also possible to use a windows resource compiler like \gnu
|
|||||||
The usage of windres is straightforward; it reads an input file
|
The usage of windres is straightforward; it reads an input file
|
||||||
describing the resources to create and outputs a resource file.
|
describing the resources to create and outputs a resource file.
|
||||||
|
|
||||||
A typical invocation of windres would be
|
A typical invocation of \file{windres} would be
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
windres -i mystrings.rc -o mystrings.res
|
windres -i mystrings.rc -o mystrings.res
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
@ -4039,7 +4242,7 @@ windows API calls.
|
|||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
Some of these will be described below.
|
Some of these will be described below.
|
||||||
\begin{Using string tables.}
|
\section{Using string tables.}
|
||||||
String tables can be used to store and retrieve large collections of
|
String tables can be used to store and retrieve large collections of
|
||||||
strings in your application.
|
strings in your application.
|
||||||
|
|
||||||
@ -4085,8 +4288,8 @@ which can then be used. Both calls are in the windows unit.
|
|||||||
|
|
||||||
\section{Inserting version information}
|
\section{Inserting version information}
|
||||||
|
|
||||||
The win32 API allows to store versioninformation in your binaries.
|
The win32 API allows to store version information in your binaries.
|
||||||
This information can be made visible with the windows Explorer, by
|
This information can be made visible with the \windows Explorer, by
|
||||||
right-clicking on the executable or library, and selecting the
|
right-clicking on the executable or library, and selecting the
|
||||||
'Properties' menu. In the tab 'Version' the version information will
|
'Properties' menu. In the tab 'Version' the version information will
|
||||||
be displayed.
|
be displayed.
|
||||||
@ -4126,11 +4329,11 @@ explorer.
|
|||||||
The Free Component Library comes with a unit (\file{fileinfo}) that allows
|
The Free Component Library comes with a unit (\file{fileinfo}) that allows
|
||||||
to extract and view version information in a straightforward and easy manner;
|
to extract and view version information in a straightforward and easy manner;
|
||||||
the demo program that comes with it (\file{showver}) shows version information
|
the demo program that comes with it (\file{showver}) shows version information
|
||||||
on an arbitrary executable or DLL.
|
for an arbitrary executable or DLL.
|
||||||
|
|
||||||
\section{Inserting an application icon}
|
\section{Inserting an application icon}
|
||||||
|
|
||||||
When windows shows an executable in the explorer, it looks for an icon
|
When \windows shows an executable in the Explorer, it looks for an icon
|
||||||
in the executable to show in front of the filename, the application
|
in the executable to show in front of the filename, the application
|
||||||
icon.
|
icon.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user