This article discusses using routines from EMemLeaks unit that can be used to mark (name) objects and other memory blocks. This is useful for memory leaks and other memory problems (name can help to identify object or otherwise anonymous memory block). To learn about other logging features in EurekaLog - see this article. EMemLeaksYou can set a name for any memory block allocated via EurekaLog memory manager (when leaks checking is active). MemLeaksName is a basic function for this task. For example:
GetMem(P, 1024);
Here is how anonymous P memory block looks in leak and dump reports:
$06961F90 x 1 DATA [Data at $06961F90] 1024 bytes (total of 1024 bytes) (00318491){Project70.exe} [00718491] Unit62.TForm62.Button1Click (Line 33, "Unit62.pas") + $5 (00247C57){Project70.exe} [00647C57] Vcl.Controls.TControl.Click (Line 7442, "Vcl.Controls.pas") + $8 ...
It is hard to understand what this leak is
And here is how it looks after naming it with MemLeaksName:
$06F91F90 x 1 DATA [[P variable] Data at $06F91F90] 1024 bytes (total of 1024 bytes) (00318491){Project70.exe} [00718491] Unit62.TForm62.Button1Click (Line 33, "Unit62.pas") + $5 (00247C57){Project70.exe} [00647C57] Vcl.Controls.TControl.Click (Line 7442, "Vcl.Controls.pas") + $8 ...
Now leak will show assigned name ("P variable")
You can convert any of the dynamically allocated types to a pointer. For example:
MemLeaksName(Pointer(fmMain), 'Main Form');
The exception to this rule: strings and dynamic arrays. These types have headers at negative offsets - therefore you can not pass these types to MemLeaksName function directly. Use:
S := 'Message';
EurekaLog is capable to extract some information about variables (for example, content of the string, dimensions of dynamic array, class name of objects, names of components). Therefore, it is not necessary to specify all tiny details.
BTW, you can change name again at any time.
Grouping child blocks with parentsYou can also define a parent-child relationship between two memory blocks. These relationships will be using for grouping and merging of memory blocks during leaks checking or dumping (see CheckHeap or DumpAllocationsToFile function). For example:
MemLeaksOwn(Pointer(fmDialog), Pointer(Stream));
This makes Stream a child of fmDialog. This means that Stream will not appear in reports. Instead - its size will be added to fmDialog.
Here is how fmDialog and Stream will look in leak and dump reports before grouping:
Two independent leaks will be shown
And here is when you indicate that fmDialog is the owner of the stream:
Only parent block is shown, sizes are summed
Such construct is used to indicate ownership. Basically, it says that fmDialog is responsible for deleting Stream. If you want to give ownership to external code, simply use:
MemLeaksOwn(nil, Pointer(Stream));
This code will remove parent-child relationship.
You can also assign and name at the same time:
MemLeaksOwn(Pointer(fmDialog), Pointer(Stream), 'Stream for Dialog Form');
Of course, there are separate functions for strings and dynamic arrays:
MemLeaksOwnStr(Pointer(fmDialog), Pointer(S), 'Message for Dialog');
See also:
|