Optimize heap memory

You can use the following techniques to optimize memory usage:

  • eliminate memory leaks
  • shorten the life cycle of heap objects
  • reduce the overhead of allocated objects
  • configure the allocator

Another optimization technique is to shorten the life cycle of the heap object. This technique lets the allocator reclaim memory faster, and allows it to be immediately used for new heap objects, which, over time, reduces the maximum amount of memory required.

Always attempt to free objects in the same function as they are allocated, unless it is an allocation function. An allocation function is a function that returns or stores a heap object to be used after this function exits. A good pattern of local memory allocation looks like this:

p=(type *)malloc(sizeof(type));
do_something(p);
free(p);
p=NULL;
do_something_else();

After the pointer is used, it is freed, then nullified. Other processes are then free to use the memory. In addition, try to avoid creating aliases for heap variables because it usually makes code less readable, more error prone, and difficult to analyze.

Memory leaks

A memory leak is a part of heap memory that was allocated but not freed, and the application cannot use the reference to that area of memory any longer. Typically, the elimination of a memory leak is critical for applications that run continuously because even a single byte leak can crash a mission critical application that runs over time.

Memory leaks can occur if your program allocates memory and then forgets to free it later. Over time, your program consumes more memory than it actually needs.

Enable memory leak detection

In a continuously running application, the following task enables memory leak detection at any particular point during program execution:
  1. Find a location in the code where you want to check for memory leaks, and insert a breakpoint.
  2. Launch the application in Debug mode with the Memory Analysis tool enabled.
  3. Change to the Memory Analysis perspective.
  4. Open the Debug view so it is available in the current perspective.
  5. When the application encounters the breakpoint you specified, open the Memory Analysis session from the Session View (by double-clicking) and select the Setting page for the Session Viewer.
  6. Click the Get Leaks button.
    Before you resume the process, take note that no new data is available in the Session Viewer because the memory analysis thread and application threads are stopped while the process is suspended by the debugging tool.
  7. Click Resume in the Debug view to resume the process' threads.
    If leaks did not appear on the Memory Problems tab of the Session Viewer, either there were no leaks, or the time given to the control thread (a special memory analysis thread that processes dynamic requests) to collect the leaks was not long enough to perform the command; and was suspended before the operation completed.
  8. Switch to the Errors page of the viewer, to review information about collected memory leaks.

Besides apparent memory leaks, an application can have other types of leaks that the memory Analysis tool cannot detect. These leaks include objects with cyclic references, accidental point matches, and left-over heap references (which can be converted to apparent leaks by nullifying objects that refer to the heap). If you continue to see the heap grow after eliminating apparent leaks, you should manually inspect some of the allocations. You can do this after the program terminates (completes), or you can stop the program and inspect the current heap state at any time using the debugging tool.

Track heap usage

You can use the QNX System Information perspective to examine the memory of your target system:

  • Find memory errors and leaks
  • Examine statistical information from the memory allocator

Malloc Information view

The Malloc Information view shows statistical information from the general-purpose, process-level memory allocator:

Screen showing the Malloc Information view.

When you select a process in the Target Navigator view, the Momentics IDE queries the target system and retrieves the allocator's statistics. The Momentics IDE gathers statistics for the number of bytes that are allocated, in use, as well as overhead.

The view includes the following panes:

Total Heap

The Total Heap pane shows your total heap memory, which is the sum of the following states of memory:
  • used (dark blue)
  • overhead (turquoise)
  • free (lavender)

The Total Heap number in the Malloc Information view is an accurate number that the Momentics IDE gets from the libmalloc library. However, the heap size number in the Memory Information view and System Resource view is an estimated number. To get the actual heap size allocated by a process, see the Malloc Information view. To get an overview about what the memory allocation pattern looks like for a process, see the Memory Information view.

The bar chart shows the relative size of each heap.

Calls Made

The Calls Made pane shows the number of times a process has allocated, freed, or reallocated memory by calling malloc, free, and realloc functions. (See the BlackBerry 10 OS C Library Reference.)

Core Requests

The Core Requests pane shows the number of allocations that the system allocator automatically made to accommodate the needs of the program you selected in the Target Navigator view. The system allocator typically dispenses memory in increments of 4 KB (one page).

The number of allocations never equals the number of deallocations, because when the program starts, it allocates memory that isn't released until it terminates.

Distribution

The Distribution pane shows a distribution of the memory allocation sizes. The pane includes the following columns:

Byte Range
The size range of the memory blocks.
Allocations
The total number of calls that allocate memory.
Deallocations
The total number of calls that free memory.
Outstanding
The remaining number of allocated blocks. The value is equal to the number of allocated blocks minus the number of deallocated blocks.
% Returned
The ratio of freed blocks to allocated blocks, expressed as a percentage. The value is calculated as the number of deallocations divided by the number of allocations.
Usage (min/max)
The calculated minimum and maximum memory usage for a byte range. The values are calculated by multiplying the number of allocated blocks by the minimum and maximum sizes of the range. For example, if the 65–128 byte range had two blocks allocated, the usage would be 130/160. You should use these values for estimated memory usage only; the actual memory usage usually lies somewhere in between.

History

The History pane shows a chronology of the heap usage shown in the Total Heap pane. The pane automatically rescales as the selected process increases its total heap.

The History pane updates the data every second, with a granularity of 1 KB. Thus, two 512-byte allocations made over several seconds trigger one update.

You can choose to hide or show the Distribution and History panes:

  1. In the Malloc Information view's title bar, click the dropdown menu button Dropdown Menu icon, followed by Show.
  2. Click the pane you want shown.

Last modified: 2015-03-31



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus