Next: , Up: The gnatmem Tool


22.3.1 Running gnatmem

gnatmem makes use of the output created by the special version of allocation and deallocation routines that record call information. This allows to obtain accurate dynamic memory usage history at a minimal cost to the execution speed. Note however, that gnatmem is not supported on all platforms (currently, it is supported on AIX, HP-UX, GNU/Linux, Solaris and Windows NT/2000/XP (x86).

The gnatmem command has the form

     
     
           $ gnatmem [switches] user_program

The program must have been linked with the instrumented version of the allocation and deallocation routines. This is done by linking with the libgmem.a library. For correct symbolic backtrace information, the user program should be compiled with debugging options (see Switches for gcc). For example to build my_program:

     $ gnatmake -g my_program -largs -lgmem

As library libgmem.a contains an alternate body for package System.Memory, s-memory.adb should not be compiled and linked when an executable is linked with library libgmem.a. It is then not recommended to use gnatmake with switch -a.

When my_program is executed, the file gmem.out is produced. This file contains information about all allocations and deallocations performed by the program. It is produced by the instrumented allocations and deallocations routines and will be used by gnatmem.

In order to produce symbolic backtrace information for allocations and deallocations performed by the GNAT run-time library, you need to use a version of that library that has been compiled with the -g switch (see Rebuilding the GNAT Run-Time Library).

Gnatmem must be supplied with the gmem.out file and the executable to examine. If the location of gmem.out file was not explicitly supplied by -i switch, gnatmem will assume that this file can be found in the current directory. For example, after you have executed my_program, gmem.out can be analyzed by gnatmem using the command:

     $ gnatmem my_program

This will produce the output with the following format:

*************** debut cc

     $ gnatmem my_program
     
     Global information
     ------------------
        Total number of allocations        :  45
        Total number of deallocations      :   6
        Final Water Mark (non freed mem)   :  11.29 Kilobytes
        High Water Mark                    :  11.40 Kilobytes
     
     .
     .
     .
     Allocation Root # 2
     -------------------
      Number of non freed allocations    :  11
      Final Water Mark (non freed mem)   :   1.16 Kilobytes
      High Water Mark                    :   1.27 Kilobytes
      Backtrace                          :
        my_program.adb:23 my_program.alloc
     .
     .
     .

The first block of output gives general information. In this case, the Ada construct “new” was executed 45 times, and only 6 calls to an Unchecked_Deallocation routine occurred.

Subsequent paragraphs display information on all allocation roots. An allocation root is a specific point in the execution of the program that generates some dynamic allocation, such as a “new” construct. This root is represented by an execution backtrace (or subprogram call stack). By default the backtrace depth for allocations roots is 1, so that a root corresponds exactly to a source location. The backtrace can be made deeper, to make the root more specific.