The Allocation profiler traces the memory use in profiled modules during the application run. This topic provides an overview of the profiler:
You use the Allocation profiler to find memory leaks in your code. The profiler monitors allocations and deallocations of memory blocks during the application run and tracks calls to the memory management routines.
The profiler traces memory in both managed and unmanaged (native-code) applications (both 32-bit and 64-bit).
The profiler collects mass statistics on memory usage, for example:
The number of and the size of allocated memory block and created objects.
The size of these blocks and objects in memory.
The creation (or allocation) point of each object or memory block, and the stack of function calls for it
References between managed objects.
The usage of allocated memory blocks.
The Allocation profiler operates during the entire run of the application. It takes no account of AQTime tools that enable or disable profiling: triggers, the Enable/Disable Profiling toolbar item, the “Enable Profiling” and “Disable Profiling”actions.
By default, the profiler does not track allocations and deallocations of memory blocks. To enable this functionality, enable the Check system memory allocations option of the Allocation profiler. To get to the option, select Options > Options from AQTime’s main menu, then choose Profilers > Allocation > Allocation Profiler from the tree on the left.select Tools > Options from Visual Studio’s main menu, and then choose AQTime > Profilers > Allocation > Allocation Profiler from the tree on the left.select AQTime > Options from Embarcadero RAD Studio’s main menu, then choose Profilers > Allocation > Allocation Profiler from the tree on the left.
Typically, the profiler generates lots of results. This occurs because the number of classes in modern applications is very large.
To decrease the amount of profiling results, you can specify which classes you want to trace. You do this by creating profiling areas of the class level in your project. The profiler will analyze only those classes that are mentioned in these areas. (If an area contains source files, namespaces or modules, the profiler will analyze all the classes in these source files, namespaces or modules).
Profiling areas do not work for memory allocations. That is, the profiler tracks allocations and deallocations of memory blocks regardless of any areas defined in your project.
If you are going to track classes, make sure that you have checked one or more class-level areas before starting profiling. Otherwise, you may get empty results. The reason for this is
that the profiler does not notify you when no class-level areas are selected, because you may want to profile non-class memory management routines such as
alloc (even .NET applications may include unmanaged sections that hold calls to these routines), and by default, non-class memory management routines are not profiled (the option Check system memory allocations is off by default).
See also important notes below for some specifics of tracking classes with AQTime.
By default, the Allocation profiler includes all the calls it detects in the call stacks. If needed, you can control which modules, classes and methods are to be included in the call stacks. You do this in the Collect Stack Information Pane. For information on specifying the stack areas of modules that will be included in the stack, see Specifying Modules to Be Included Into the Call Stack.
With the Allocation profiler you can analyze the use of objects and memory blocks in your unmanaged applications, that is:
Determine whether objects and memory blocks remain in memory after the application run is over.
The Allocation profiler traces calls to memory management functions provided by the programming language and calls to Windows memory management functions (calls to these functions are traced if the Check system memory allocations option is enabled). For detailed information on profiling different types of unmanaged applications, see the topics of the Analyzing Applications section.
Check whether the application exceeds the bounds of the allocated memory block.
If the Check Memory Bounds option is enabled, the profiler traces whether the application wrote to addresses above the upper or below the lower bound of an allocated memory block. For more information, see Checking Bounds of Memory Blocks.
Track memory blocks that are referred to after they have been released.
Generally, when a block is released, it is marked as free, but its data may still be available and further instructions may successfully read data from it. If the Fill released memory blocks option is enabled, AQTime overwrites the actual data of the block upon its release. So, if there is an attempt to read data from a released block, an invalid value will be returned, which will allow you to find invalid references. See the Tracing Attempts to Access Released Memory topic for details.
Note that by default, AQTime detects known memory leaks produced by third-party libraries, such as MFC, VCL and others (such leaks are called standard leaks) and does not display them in profiling results. This helps you avoid memory problems of IDE compilers, VCL components, Microsoft Foundation Classes and others. For more information, see Filtering Results.
When you profile your managed application with the Allocation profiler, AQTime traces all the memory allocated by the application. When the application run is over, the common language runtime reclaims all memory allocated for the application objects. Therefore, after the application has been closed, the memory allocated for it is released. However, the Allocation profiler will report that some objects still exist. This can happen due to the following:
The Allocation profiler can report about unreleased objects after the application termination, because the profiler collects the final statistics before the Common Language Runtime calls the garbage collector to free the memory.
Another reason is that .NET applications can still have actual memory leaks although the Garbage Collector significantly reduces the chance of these leaks.
The nature of .NET leaks is different from that of leaks in unmanaged applications. Leaks in unmanaged applications appear if an object or some resource has been allocated but is not released when it is not needed anymore. Leaks in managed applications can appear if root objects (such as global variables) have direct or indirect references to some objects. These objects are not destroyed by the Garbage Collector, and thus their lifetime can equal the application’s run-time. Moreover, if objects are not deleted at some points of application execution, you may get memory overflow.
Our Web site holds an article (http://support.smartbear.com/articles/aqtime/net-allocation-profiler/) that gives examples of potential memory leaks in .NET applications and describes how you can find them using the Allocation profiler of AQTime.
As the run-time releases memory when the application is being closed, the final statistics may not be very interesting. That is why the Allocation profiler is used mainly to monitor the existing application objects during the run. To obtain results during the application run, select Run > Get Results from AQTime’s main menuselect AQTime > Get Results from Visual Studio’s menuselect AQTime > Get Results from RAD Studio’s main menu, or use the Get Results action. For more information, see Allocation Profiler - Analyzing .NET Applications.
Since the Allocation profiler generates large amount of data, you may face some difficulties when analyzing results. Therefore, AQTime provides you with a number of built-in filters that allow you to hide unnecessary information. For a detailed description of the available filters, see Filtering Results.
|Tip:||Working with a great number of results can also cause performance problems and out-of-memory issues in AQTime. See the Reduce the Amount of Collected Allocation Data topic for some recommendations on how to reduce the amount of collected data.|
Some memory leaks in the application may be produced by standard libraries (such as VCL or MFC). AQTime detects such standard leaks and automatically excludes them from the profiling results. If you want to see standard leaks, disable the Filter Standard Leaks option (it is enabled by default).
An application may include classes, in which all the methods (including constructors) are inherited, but not overridden (for instance, a class may introduce some new properties or fields, but it may not define new methods or override existing ones). These classes are not listed in the Setup panel, but AQTime will profile them if you enable the All Project Modules option. The Allocation profiler traces instantiation of such classes as allocations of memory blocks, but not as allocations of objects. So, you may notice that the Allocation profiler does not report about leaked objects, but about memory leaks.
To solve the problem, create a new or override an existing method of the class (for instance, the object’s constructor). Note that if a method is not called in your application, the compiler may not include it in the application’s binary code. So, even the classes that introduce new methods may become a class described above. To solve the problem in this case, disable optimization in compiler settings.
The amount of allocated memory displayed for your application by AQTime may differ from the amount of memory shown in the Task Manager. This happens because AQTime displays the memory that is currently allocated by the application’s memory manager for all live objects being profiled (the Allocation profiler traces only those objects whose classes are included in class-level areas).
In the Task Manager window, you see the memory size that is allocated by the operating system’s memory manager for the application. Some part of this memory may not be used at the moment, but it is still allocated by the application’s memory manager (for instance, for future use). In certain cases, deallocated memory blocks may not be returned to the operating system’s memory manager, so the operating system “thinks” that these blocks are still being allocated by the application. There are also other possible reasons. So, the difference you see is caused by the peculiarities of memory management in the operating system and in the application.
The Allocation profiler is closely integrated with the Monitor panel and can display its results during the profiler run, as they are received. See Using the Monitor Panel With the Allocation Profiler.