Calculating memory reserved by a process

QNX SDP8.0System ArchitectureDeveloperUser

You can use vmstat files to get information about system and per-process memory usage. The pmap files are another source of per-process memory information. The use of shared objects must also be taken into consideration when measuring memory consumption.

Per-process memory consumption and shared objects

The memory that a process uses is provided via mapping: the QNX OS process manager maps physical memory into a process's address space. The memory is organized in fixed-sized chunks called pages (typically 4 KB each), which are the units the memory manager deals with. The statistics for each mapped memory region includes the amount of memory, if any, that the region reserves for the process.

Because these mappings can be shared, determining how much each process contributes to total system memory use can be complex. Every process maps multiple shared objects, including its own executable and the C library. In the pmap list, shared mapping of these objects shows up as consuming no memory because the memory reservation is assumed by the underlying object.

Additionally, systems can have shared memory objects that are not mapped by any process: a process can create this kind of object with a call to shm_open() and never map it. That process can exit and leave the shared memory object to linger (which is required for POSIX semantics).

Thus, while there are methods that allow you to view or calculate the memory reserved for a specific process, a full system analysis of memory consumption requires a careful consideration of all shared objects, along with which processes (if any) map them.

(For a detailed discussion of system and process memory, go to Working with Memory in the QNX OS Programmer's Guide and the mmap() entry in the C Library Reference.)

Memory reservation from reading the vmstat files

You can access memory statistics for an individual process using the appropriate instance of /proc/pid/vmstat, where pid is the process ID. The statistics include the as_stats.anon.rsv parameter, which represents the total memory reserved by the process.

The /proc/vm/stats file provides the totaled values for all /proc/pid/vmstat instances.

To learn more about these file output, go to The vmstat files.

(Also, the following section includes an example of vmstat file content.)

Memory reservation from reading the pmap file

Reading the pmap file gives you a more detailed look at the memory mapping of the process. You can find how much memory is reserved by a process by summing selected parameters in the file's output. You can read the file using cat:

cat /proc/pid/pmap
            

For example (to make it easier to read, a return character () is added to break long lines):

vaddr,size,flags,prot,maxprot,dev,ino,offset,rsv,guardsize,refcnt,mapcnt,path,asinfo
0x0000000000002000,0x0000000000080000,0x00083002,0x03,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x0000000000080000,0x00001000,0x00000000,0x0000035b,{stack},{sysram}
0x0000000008048000,0x0000000000001000,0x00000031,0x05,0x0d,0x0000040b,0x00000000000d600b,
0x0000000000000000,0x0000000000000000,0x00000000,0x00000008,0x00000006,/system/local/bin/mmap_demo,{sysram}
0x0000000008049000,0x0000000000001000,0x00000032,0x01,0x0f,0x0000040b,0x00000000000d600b,
0x0000000000001000,0x0000000000001000,0x00000000,0x00000008,0x00000006,/system/local/bin/mmap_demo,{sysram}
0x000000000804a000,0x0000000000001000,0x00000032,0x03,0x0f,0x0000040b,0x00000000000d600b,
0x0000000000002000,0x0000000000001000,0x00000000,0x00000008,0x00000006,/system/local/bin/mmap_demo,{sysram}
0x0000000009048000,0x000000000000d000,0x00080002,0x03,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x000000000000d000,0x00000000,0x00000000,0x0000035b,{heap},{sysram}
0x0000000009055000,0x0000000000002000,0x00080001,0x03,0x0f,0x00000001,0x9fa48eb407e62f83,
0x0000000000000000,0x0000000000000000,0x00000000,0x00000002,0x00000001,**anonymous**,{unknown}
0x0000000009057000,0x00000000f4240000,0x00080002,0x00,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x0000000000000000,0x00000000,0x00000000,0x0000035b,{heap},{sysram}
0x0000000100000000,0x0000000000036000,0x00010031,0x05,0x0d,0x00000802,0x000000008000001c,
0x0000000000000000,0x0000000000000000,0x00000000,0x0000024b,0x00000249,/proc/boot/ldqnx-64.so.2,{ram}
0x0000000100036000,0x0000000000002000,0x00010032,0x01,0x0f,0x00000802,0x000000008000001c,
0x0000000000036000,0x0000000000002000,0x00000000,0x0000024b,0x00000249,/proc/boot/ldqnx-64.so.2,{ram}
0x0000000100038000,0x0000000000001000,0x00010032,0x03,0x0f,0x00000802,0x000000008000001c,
0x0000000000038000,0x0000000000001000,0x00000000,0x0000024b,0x00000249,/proc/boot/ldqnx-64.so.2,{ram}
0x0000000100039000,0x0000000000001000,0x00080032,0x03,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x0000000000001000,0x00000000,0x00000000,0x0000035b,{bss},{sysram}
0x000000010003a000,0x00000000000a6000,0x00010031,0x05,0x0d,0x00000802,0x0000000080000010,
0x0000000000000000,0x0000000000000000,0x00000000,0x0000024b,0x00000249,/proc/boot/libc.so.6,{ram}
0x00000001000e0000,0x0000000000004000,0x00080032,0x01,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x0000000000004000,0x00000000,0x00000000,0x0000035b,{bss},{sysram}
0x00000001000e4000,0x0000000000002000,0x00010032,0x03,0x0f,0x00000802,0x0000000080000010,
0x00000000000aa000,0x0000000000002000,0x00000000,0x0000024b,0x00000249,/proc/boot/libc.so.6,{ram}
0x00000001000e6000,0x0000000000006000,0x00080032,0x03,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x0000000000006000,0x00000000,0x00000000,0x0000035b,{bss},{sysram}
0x00000001000ec000,0x000000000001c000,0x00010031,0x05,0x0d,0x00000802,0x0000000080000011,
0x0000000000000000,0x0000000000000000,0x00000000,0x0000024b,0x00000249,/proc/boot/libgcc_s.so.1,{ram}
0x0000000100108000,0x0000000000001000,0x00080032,0x01,0x0f,0x00000001,0x0000000000000003,
0x0000000000000000,0x0000000000001000,0x00000000,0x00000000,0x0000035b,{bss},{sysram}
0x0000000100109000,0x0000000000001000,0x00010032,0x03,0x0f,0x00000802,0x0000000080000011,
0x000000000001d000,0x0000000000001000,0x00000000,0x0000024b,0x00000249,/proc/boot/libgcc_s.so.1,{ram}
0x0000000180000000,0x0000000000004000,0x00000002,0x03,0x0f,0x0000040c,0x000000000085890b,
0x0000000000000000,0x0000000000004000,0x00000000,0x00000004,0x00000002,/data/home/user/mmap_demo.qISt3b,{sysram}
0x0000000180004000,0x0000000000004000,0x00000001,0x03,0x0f,0x0000040c,0x000000000085890b,
0x0000000000000000,0x0000000000000000,0x00000000,0x00000004,0x00000002,/data/home/user/mmap_demo.qISt3b,{sysram}
            

The first line lists the parameter names in the order in which they appear in subsequent lines. In subsequent lines, the first two parameters show the virtual address (vaddr) and maximum size of memory that it can reserve. For example, in the following entry, the virtual address 0x0000000008048000 can reserve 4 KB of memory (one 4K page):

0x0000000008048000,0x0000000000001000,0x00000031,0x05,0x0d,0x0000040b,0x00000000000d600b,
0x0000000000000000,0x0000000000000000,0x00000000,0x00000008,0x00000006,/system/local/bin/mmap_demo,{sysram}

The next two parameters, flags and prot, show the mapped memory and page protection flags. In this example, the values represent a shared mapping with read-only and executable permissions.

Note:
The prot values correspond to the protection bits defined in sys/mman.h, but are right-shifted by 8. For more information, go to the mmap() entry in the QNX OS C Library Reference.

The ninth parameter is the reservation parameter (rsv) and it is crucial. It shows how many bytes are billed to this process for the mapping. If it's a private mapping of a shared object, the value is the same as the size of the mapping because the mapping requires that the system allocate new pages for it with a copy of the contents of the object (e.g., a temporary file). In contrast, a shared mapping of the same object has a value of 0, as in the example above. (For more details, go to The pmap parameters.)

The second-last parameter, path, shows the mapped object. This object can be a file, a shared-memory object, or a single anonymous object that is used to map the process’s stacks and heaps. The asinfo parameter, the last one, is the name of the asinfo entry that backs the mapping (the system page's asinfo entries describe different sections of the system memory map).

(For a description of all parameters, go to The pmap parameters.)

You can use the size, flags, prot, and rsv parameters to calculate the reserved memory of the process. In the second row, these parameters have the following values:
size
0x0000000000001000 (4096 bytes)
flags
0x00000031 (MAP_FIXED, MAP_ELF, MAP_SHARED)
prot
0x05 (PROT_READ, PROT_EXEC)
rsv
0x0000000000000000 (0 bytes)

This region is type code (read only). It is a shared, read-only mapping of an object and has reserved 0 KB of memory.

The fifth row is a heap region and has the following parameter values:
size
0x000000000000d000 (52 KB)
flags
0x00080002 (MAP_ANON, MAP_PRIVATE)
prot
0x03 (PROT_READ, PROT_WRITE)
rsv
0x000000000000d000 (52 KB)
Analyzing the output line by line produces the table below with the total memory reserved at the bottom:
Region type Row numbers Reserved memory in KB Total in KB
Code 2, 8, 12, 16 0 0
Data (Read Only) 3, 9, 13, 17 4, 8, 16, 4 32
Data (Read/Write) 4, 6, 10, 11, 14, 15, 18-20 4, 0, 4, 4, 8, 24, 4, 16, 0 64
Stack 1 512 512
Heap 5, 7 52 52
Total memory reserved: 660
Reading the vmstat file for the process, you can see that the amount of reserved memory (as_stat.anon_rsv) is indeed 660 KB:
# cat /proc/103751721/vmstat
as_stats.vm_region=21
as_stats.vm_map=16
as_stats.map_size=0xf43e7 (3.815GB)
as_stats.map_phys=0xfb (1004.000kB)
as_stats.map_shared=0x102 (1.007MB)
as_stats.map_private=0xa5 (660.000kB)
as_stats.rss=0x1a7 (1.652MB)
as_stats.anon_rsv=0xa5 (660.000kB)
as_stats.rlimit_data=0xd (52.000kB)
                
Page updated: