Search code examples
linuxmemorytop-command

RES != CODE + DATA in the output information of the top command,why?


what 'man top' said is: RES = CODE + DATA

q: RES -- Resident size (kb)
The non-swapped physical memory a task has used.
RES = CODE + DATA.

r: CODE -- Code size (kb)
The amount of physical memory devoted to executable code, also known as the 'text        resident set' size or TRS.

s: DATA -- Data+Stack size (kb)
The amount of physical memory devoted to other than executable code, also known as the   'data >resident set' size or DRS.

what when i run 'top -p 4258',i get the following:

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  CODE DATA COMMAND
258 root      16   0  3160 1796 1328 S  0.0  0.3   0:00.10  476  416 bash

1796 != 476+416

why?

ps: linux distribution:

linux-iguu:~ # lsb_release -a
LSB Version:    core-2.0-noarch:core-3.0-noarch:core-2.0-ia32:core-3.0-ia32:desktop-3.1-ia32:desktop-3.1-noarch:graphics-2.0-ia32:graphics-2.0-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: SUSE LINUX
Description:    SUSE Linux Enterprise Server 9 (i586)
Release:        9
Codename:       n/a

kernel version:

linux-iguu:~ # uname -a
Linux linux-iguu 2.6.16.60-0.21-default #1 Tue May 6 12:41:02 UTC 2008 i686 i686 i386 GNU/Linux

Solution

  • I'll explain this with the help of an example of what happens when a program allocates and uses memory. Specifically, this program:

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    
    int main(){
    
            int *data, size, count, i;
    
            printf( "fyi: your ints are %d bytes large\n", sizeof(int) );
    
            printf( "Enter number of ints to malloc: " );
            scanf( "%d", &size );
            data = malloc( sizeof(int) * size );
            if( !data ){
                    perror( "failed to malloc" );
                    exit( EXIT_FAILURE );
            }
    
            printf( "Enter number of ints to initialize: " );
            scanf( "%d", &count );
            for( i = 0; i < count; i++ ){
                    data[i] = 1337;
            }
    
            printf( "I'm going to hang out here until you hit <enter>" );
            while( getchar() != '\n' );
            while( getchar() != '\n' );
    
            exit( EXIT_SUCCESS );
    }
    

    This is a simple program that asks you how many integers to allocate, allocates them, asks how many of those integers to initialize, and then initializes them. For a run where I allocate 1250000 integers and initialize 500000 of them:

    $ ./a.out
    fyi: your ints are 4 bytes large
    Enter number of ints to malloc: 1250000
    Enter number of ints to initialize: 500000
    

    Top reports the following information:

      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  SWAP CODE DATA COMMAND
    <program start>
    11129 xxxxxxx   16   0  3628  408  336 S    0  0.0   0:00.00 3220    4  124 a.out
    <allocate 1250000 ints>
    11129 xxxxxxx   16   0  8512  476  392 S    0  0.0   0:00.00 8036    4 5008 a.out
    <initialize 500000 ints>
    11129 xxxxxxx   15   0  8512 2432  396 S    0  0.0   0:00.00 6080    4 5008 a.out
    

    The relevant information is:

                              DATA CODE  RES VIRT
    before allocation:         124    4  408 3628
    after 5MB allocation:     5008    4  476 8512
    after 2MB initialization: 5008    4 2432 8512
    

    After I malloc'd 5MB of data, both VIRT and DATA increased by ~5MB, but RES did not. RES did increase after I touched 2MB of the integers I allocated, but DATA and VIRT stayed the same.

    VIRT is the total amount of virtual memory used by the process, including what is shared and what is over-committed. DATA is the amount of virtual memory used that isn't shared and that isn't code-text. I.e., it is the virtual stack and heap of the process. RES is not virtual: it is a measurment of how much memory the process is actually using at that specific time.

    So in your case, the large inequality CODE+DATA < RES is likely the shared libraries included by the process. In my example (and yours), SHR+CODE+DATA is a closer approximation to RES.

    Hope this helps. There's a lot of hand-waving and voodoo associated with top and ps. There are many articles (rants?) online about the descrepancies. E.g., this and this.