Finding Memory Leaks and Memory Growth With Intel® Inspector XE

There are several ways that you can use the Intel® Inspector XE to get insight into how your applications use memory. This guide helps you better understand the different types of information that the Intel Inspector XE can give you about your application’s memory usage and how you can use that information to find and fix issues in your application.

Intel Inspector XE provides two main categories of memory usage information about an application:

  • Memory growth information about memory that has been allocated, but not yet freed
  • Memory leak information about memory that has been allocated but can no longer be freed because the application has lost all references to it

You can control collection of this information via the GUI (standalone or integrated into the Microsoft Visual Studio* IDE), via the CLI, or with APIs present in the Intel Inspector XE ittnotify APIs.

This guide starts by walking you through GUI use, follows with information about using the CLI, and concludes with a section on using the Intel Inspector XE APIs to gather leak and growth information.

Memory Leak and Growth Configuration in the GUI

You can configure the Intel Inspector XE to collect memory usage information by selecting appropriate checkbox values in the Configure Analysis Type window:

The checkboxes that control memory leak and growth detection are:

  • Detect memory leaks upon application exit
  • Enable interactive memory growth detection
  • Enable on-demand leak detection
  • Detect still-allocated memory at application

Each of these checkboxes is described in more detail in the following sections.

Memory Leaks

Memory Leak Detection at Application End

A memory leak occurs when an application allocates memory, but loses all references to that memory. As a result, that piece of memory can neither be used by the application (because the application has no reference to it), nor can it be be freed (again because the application has no reference to it to pass to the free routine). An application that leaks enough memory may run out of address space and fail, or cause the system to run out of swap space, resulting in system-wide stability or performance issues.

When you select the Detect memory leaks upon application exit checkbox on the Configure Analysis Type window, the Intel Inspector XE detects all memory leaks present when the application exits. This option is enabled by default in all preset memory error analysis types.

At the end of the analysis run, the GUI displays memory leaks as Memory leak problems in the Problems pane on the Summary window. See for example, problem P2 in the following screenshot:

One obvious limitation of detecting memory leaks when the application exits is that the application needs to exit in order for the Intel Inspector XE to detect leaks. If the application is killed, or stopped with the Stop button, the Intel Inspector XE does not detect leaks. Thus this option is not appropriate for server processes or other applications that do not exit. This brings us to our next section.

On-Demand Leak Detection

Finding leaks when an application exits is not always useful. Sometimes, you have an application that doesn’t exit. Other times, even if your application does exit, you want to focus specifically on leaks that occur over a specific interval of your application’s run, or during a specific phase or action of your application. For instance, if you want to find the leaks that occur after a particular shared library loads, or when performaing a specific action in your application’s GUI.

Intel Inspector XE provides the ability to identify leaks that occur at or during a specific time interval with an on-demand leak detection functionality.

When you select the Enable on-demand memory leak detection checkbox on the Configure Analysis Type window, you activate the on-demand leak detection functionality. Selection is the default setting for the Detect Memory Problems and Locate Memory Problems (mi2 and mi3) memory error analysis types.

Activating on-demand leak detection enables two buttons on the right side of the GUI during analysis. One is marked Reset Leak Tracking and the other is marked Find Leaks:

By default, the Intel Inspector XE tracks all memory allocations when your application starts. As a result, if any of these allocations are leaked, they appear as a Memory leak problem. However, if you click the Reset Leak Tracking button, the Intel Inspector XE discards information about earlier allocations, and tracks leaks only for those allocations that occur after the Reset Leak Tracking button is clicked.

We will describe some examples of this button use in more detail after describing the use of the Find Leaks button.

When your application reaches a point where you want to see if there have been any leaks, click the Find Leaks button. Intel Inspector XE immediately looks for and shows any memory that your application has leaked. Newly found leaks appear in the Problems pane of the Summary window as Memory leak problems, while analysis continues on the application, as shown in the following screenshot:

Even if you do not reset the leak baseline (click the Reset Leak Tracking button) each report, including the final one at application end, shows leaks that occurred since the previous report. This means that there is no need to reset the leak baseline unless there are portions of the application that you do not want to track for leaks.

Intel Inspector XE detects a leak when all references to the memory have gone out of scope. There may be a time after your application loses its references to a piece of memory, but before the end of the function’s scope, where the language runtime still has a reference to the memory. If you ask for a leak report in that short interval, the Intel Inspector XE does not show that leak because the language runtime still holds an internal reference to the memory. As a result, the Intel Inspector XE believes that piece of memory is still in use. However, that leak is not lost; it shows up on any leak report generated after the runtime reference scope closes (so long as the leak baseline is not reset).

Usage Examples

Let’s revisit some of the scenarios described at the beginning of this section.

  • Suppose you want to find the leaks that occurred only when performing a specific GUI operation. Do this:
    1. Start up your application under the Inspector XE, making sure that the Enable on-demand leak detection checkbox is selected in the analysis configuration.
    2. Let your application run to the point where it is ready for the GUI operation you want to measure.
    3. Click the Reset Leak Tracking button, so that earlier allocations are discarded, and only allocations that follow are tracked for leaks.
    4. Perform the operation in your application’s GUI.
    5. Click the Find Leaks button to detect leaks.
    6. Open the Summary window and examine the memory leak information.
  • Suppose you want to find the leaks that occurred on allocations after a specific shared library is loaded. Do this:
    1. Start up your application under the Intel Inspector XE, making sure that the Enable on-demand leak detection checkbox is selected in the analysis configuration.
    2. Let your application run to the point where it is about to load the shared library you are interested in.
    3. Click the Reset Leak Tracking button, so that earlier allocations are discarded, and won’t pollute leak detection.
    4. Let the shared library load and run.
    5. Whenever you are interested in the leaks up to this point, click the Find Leaks button to detect leaks. This may be while the library is still present in memory, or after the library has unloaded itself.
    6. Open the Summary window to examine the memory leak information.

Using the GUI buttons to detect leaks for a running application can be like trying to hit a moving target if the application does not have obvious quiescent states. If you need finer control to reset the leak baseline or detect leaks, use the Intel Inspector XE APIs for on-demand leak detection described in the API Usage section.

Detecting leaks during the analysis run has several advantages over waiting until the application ends – you can:

  • Detect leaks for applications that do not exit, such as server processes.
  • Look specifically at leaks that might be happening in a new section of your code, or code that you have reason to believe may have problems.
  • Work on some of your issues while analysis continues to run on the rest of your application.
  • Terminate your application after a problematic section, and still collect the leak information on that section.

Memory Growth

It can be important to track how much memory your application uses, and to make sure that it uses no more memory than is expected. The memory in use includes memory that you have:

  • Allocated and still need for future calculations
  • Allocated and no longer need, but have not deallocated
  • Allocated and then leaked

Intel Inspector XE has a few ways to tell you about your application’s current memory usage.

Memory Allocated/Not Yet Deallocated

When you select the Detect still-allocated memory at application exit checkbox on the Configure Analysis Type window, the Intel Inspector XE detects any memory that was still accessible at the end of the analysis run that your application could have deallocated, but didn’t. This option is enabled by default in all preset memory error analysis types.

These allocations appear as Memory not deallocated problems in the following GUI screenshot:

Interactive Memory Growth

If you want to know how much memory is in use at a given time during the run, or how much memory is growing during a particular section of your code, you want to take advantage of the Intel Inspector XE interactive memory growth functionality.

When you select the Enable interactive memory growth detection checkbox in the Configure Analysis Type window, you activate memory growth detection functionality. Selection is the default setting for the Detect Memory Problems and Locate Memory Problems (mi2 and mi3) memory error analysis types. It is disabled by default for the Detect Leaks (mi1) type.

Activating memory growth detection enables two buttons on the right side of the GUI during analysis. One is marked Reset Growth Tracking and the other is marked Measure Growth

Just as with on-demand leak detection, during the analysis run, clicking the Reset Growth Tracking button indicates that you want this to be the starting point for detecting memory growth. If you do not click this button, the Intel Inspector XE detects all growth since the start of the application.

Note: For memory growth, the Reset Leak Tracking button is equivalent to the Set Transaction Start button in earlier versions of the Intel Inspector XE.

When you are ready to detect memory growth, click the Measure Growth button to generate a memory growth report available in the Summary window while application analysis continues:

Note: For memory growth, the Measure Growth button is equivalent to the Set Transaction End button that appeared in earlier versions of the Intel Inspector XE. However, unlike with Set Transaction End, it is possible to click Measure Growth multiple times without an intervening Reset Growth Tracking click. This allows you to take multiple growth measurements from the same starting point, and probe growth.

Memory growth reports describe the memory that has been allocated, but not (yet) deallocated from the time of the previous growth reset operation (click of the Reset Growth Tracking button), up until the time of the report. They include memory actively in use, as well as memory that has been leaked.

Unlike on-demand leak detection, a memory allocation that shows up on one growth report also shows up on the next growth report if a) you do not reset the growth baseline, and b) that memory has not been deallocated. As a result, repeated use of the Measure Growth button from a single starting point allows you to monitor the amount of unfreed memory at various points in your application’s execution.

For finer control, use the Intel Inspector XE API for interactive memory growth analysis described in the API Usage section.

You can use the information in the memory growth report to determine how much heap memory you are using, and also where you are using that memory. This can help you determine when you are keeping more information in memory than you actually need.

Interactive memory growth analysis can help you:

  • Determine why you are using more memory than you expect to be using.
  • Find memory issues that are contributing to crashes prior to the completion of the application.

 

Using the Memory Graph

Determining when to start and stop on-demand leak detection and memory growth analysis can be tricky. To help with this, Intel Inspector XE has added a real time memory usage graph that you can use to determine at what point in your program your use of memory is increasing. The memory graph is also labeled with symbols to indicate when on-demand leak detection and memory analysis buttons were pressed during the run and color coded to indicate current active range of growth analysis.

 

Memory Leak and Growth Configuration in the CLI

Memory leak detection and growth analysis are also configurable when using the CLI. Each of the leak- and growth-related checkboxes in the Configure Analysis Type window has a corresponding CLI knob that can be configured on the command line. The mapping of GUI options to CLI knobs is described in the following table:

GUI Configuration option Equivalent CLI Command Knob
Detect memory leaks upon application exit detect-leaks-on-exit
Enable interactive memory growth detection enable-memory-growth-detection
Enable on-demand leak detection enable-on-demand-leak-detection
Detect still-allocated memory at application exit still-allocated-memory

So, for example, if you wanted to analyze your application with end-of-run leak detection turned off and on-demand leak detection turned on, you could use the command:

inspxe-cl -collect mi1 -knob detect-leaks-on-exit=false  \ 
-knob enable-on-demand-leak-detection=true \ application.exe

Note that default values of these knobs are set by the analysis level. You only need to set the value of any knob where you want to change the default behavior. An easy way to get the correct set of knobs is to use the GUI (integrated or standalone) configuration page to set the checkboxes, and then use the Command Line… button in the lower right corner to get the exact command line to use.

Once your application is running, you can use the inspxe-cl –command option to control on-demand leak and growth detection with the following options:

  • Use –command with reset-leak-growth-detection to set a new start point for memory leak detection for the currently running memory error analysis.
  • Use -command with detect-leaks-growth-now to detect memory leaks and growth errors data immediately, rather than waiting for the application to terminate.

For example the command:

inspxe-cl -command detect-leaks-growth-now

generates a Memory growth report, and adds it to the current result.

Note that for both interactive memory growth and on-demand leak detection, these commands do not display current growth/leak information on the screen; they simply write the information to the result file.

API Usage

Whether you are clicking a button in the GUI or sending a command via the CLI, it is difficult to accurately reset the growth/leak baseline and/or show points for interactive memory growth and on-demand leak detection. However, these points can be executed precisely by taking advantage of the Intel Inspector XE API functions, which allow marking exactly where in your code you want to reset growth/leak baselines or generate reports.

The API consists of a reset function and a report function, with a mask value passed into the function to indicate whether it is interactive memory growth, on-demand leak detection, or both that you are resetting/reporting.

The mask values and API prototypes are defined in the header file ittnotify.h, which can be found in the Intel Inspector XE install_dir/include directory. In addition, you need to link your application with the appropriate libittnotifylibrary. (See the sections About Inspector API Support, and APIs for Custom Memory Allocation in the Intel Inspector XE documentation for more details about compiling and linking in this library, as well as using these APIs.)

  • __itt_heap_growth to indicate memory growth detection.
  • __itt_heap_leaks to indicate on-demand leak detection.
  • __itt_heap_growth + __itt_heap_leaks to trigger both features with a single call.

(Note that in Fortran, you must omit the leading underscores from mask values.)

In C/C++:

  • To reset the growth/leak baseline, use:
    void __itt_heap_reset_detection(unsigned int mask);
  • To generate a report, use:
    void __itt_heap_record(unsigned int mask);

In Fortran:

  • To reset the growth/leak baseline, use:
    subroutine itt_heap_reset_detection(mask)
    integer, iaintent(in), value:: mask
    end subroutine itt_heap_reset_detection
  • To generate a report, use:
    subroutine itt_heap_record(mask)
    integer, intent(in), value:: mask
    end subroutine itt_heap_record

You must activate the appropriate analysis configuration checkboxes in the GUI or knobs in the CLI in order for the Intel Inspector XE to use the APIs. For instance, if your application is instrumented with API calls for memory growth detection, but you don’t select the Enable interactive memory growth detection checkbox in the GUI, or set –knob enable-memory-growth-detection=true when using inspxe-cl, then no growth problems appear in the result. This allows an application to be instrumented once, and for the calls to reside and remain in the code, without affecting the output of every Intel Inspector XE run, and only be activated for the Intel Inspector XE runs where desired.

Conclusion

Beyond the basics of telling you where your application leaked memory, the Intel Inspector XE allows you to monitor your running application to find memory issues quickly and precisely. It allows you to analyze portions of your application’s execution, and track your application’s memory usage, not just its leaks. This increases your opportunities to better manage your application’s memory.

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.