Home > Net >  Size of data segment in /proc/pid/maps
Size of data segment in /proc/pid/maps

Time:08-20

I am trying to understand memory mapping in Linux, and wrote below program for the same.

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define MEM_SIZE 1*1024*1024*1024 // 1GB
#define PAGE_SIZE 4*1024
#define NO_OF_PAGES (MEM_SIZE)/(PAGE_SIZE)

// Global array of size 1 GB
int mem[MEM_SIZE/sizeof(int)] = {
                                    0,1,2,
                                };

void *func(void *args)
{
    while (1) {
        for (int i=0; i<NO_OF_PAGES; i  ) {
            mem[(i*PAGE_SIZE)/sizeof(int)] = 1; // Update first 4-bytes of each page.
        }
        // All pages are updated.
        fflush(stdout);
        printf("."); // Each dot(.) represents update of all pages in global data.
    }
    return NULL;
}
int main() {
    pthread_t t;
    pthread_create(&t, NULL, func, NULL);
    printf("A thread is continually updating all pages of global 1GB data. (pid : %d)\n", getpid());
    pthread_join(t, NULL);
    return 0;
}

It executes like this,

[ ] gcc test.c
[ ] ./a.out
A thread is continually updating all pages of global 1GB data. (pid : 4086)
.......................

Here, a thread is continually updating all pages of the global data used in this program. Hence, this process should consume ~1GB (MEM_SIZE) in memory.

But the process memory looks like below, (I can not see 1GB of data memory being used here).

[ ]# cat /proc/4086/maps
55eac3b7c000-55eac3b7d000 r--p 00000000 08:01 1197055                    /root/testing/a.out
55eac3b7d000-55eac3b7e000 r-xp 00001000 08:01 1197055                    /root/testing/a.out
55eac3b7e000-55eac3b7f000 r--p 00002000 08:01 1197055                    /root/testing/a.out
55eac3b7f000-55eac3b80000 r--p 00002000 08:01 1197055                    /root/testing/a.out
55eac3b80000-55eb03b81000 rw-p 00003000 08:01 1197055                    /root/testing/a.out
55eb047b5000-55eb047d6000 rw-p 00000000 00:00 0                          [heap]
7f19c791b000-7f19c791c000 ---p 00000000 00:00 0
7f19c791c000-7f19c811e000 rw-p 00000000 00:00 0
7f19c811e000-7f19c8140000 r--p 00000000 08:01 1969450                    /usr/lib/libc.so.6
7f19c8140000-7f19c829b000 r-xp 00022000 08:01 1969450                    /usr/lib/libc.so.6
7f19c829b000-7f19c82f2000 r--p 0017d000 08:01 1969450                    /usr/lib/libc.so.6
7f19c82f2000-7f19c82f6000 r--p 001d4000 08:01 1969450                    /usr/lib/libc.so.6
7f19c82f6000-7f19c82f8000 rw-p 001d8000 08:01 1969450                    /usr/lib/libc.so.6
7f19c82f8000-7f19c8307000 rw-p 00000000 00:00 0
7f19c8311000-7f19c8312000 r--p 00000000 08:01 1969441                    /usr/lib/ld-linux-x86-64.so.2
7f19c8312000-7f19c8338000 r-xp 00001000 08:01 1969441                    /usr/lib/ld-linux-x86-64.so.2
7f19c8338000-7f19c8342000 r--p 00027000 08:01 1969441                    /usr/lib/ld-linux-x86-64.so.2
7f19c8342000-7f19c8344000 r--p 00031000 08:01 1969441                    /usr/lib/ld-linux-x86-64.so.2
7f19c8344000-7f19c8346000 rw-p 00033000 08:01 1969441                    /usr/lib/ld-linux-x86-64.so.2
7ffe8b517000-7ffe8b538000 rw-p 00000000 00:00 0                          [stack]
7ffe8b599000-7ffe8b59d000 r--p 00000000 00:00 0                          [vvar]
7ffe8b59d000-7ffe8b59f000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]
[ ]#

Though, meminfo reflects the consumption of ~1GB.

Before starting this program:
[ ]# cat /proc/meminfo | grep 'MemFree\|SwapFree'
MemFree:         6740324 kB
SwapFree:              0 kB

and after starting the program:

[ ]# cat /proc/meminfo | grep 'MemFree\|SwapFree'
MemFree:         5699312 kB
SwapFree:              0 kB

CodePudding user response:

In the map, we can see the following zones:

  • 7f19c791b000-7f19c791c000 ---p 00000000 00:00 0 : Red zone to protect the stack of the thread = non RW 4KB long page (stack overflow detection)
  • 7f19c791c000-7f19c811e000 rw-p 00000000 00:00 0 : Stack of the thread (it grows from high to low memory addresses)
  • 55eac3b80000-55eb03b81000 rw-p 00003000 08:01 1197055 : the 1 GB memory space (mem[] table) 4KB

You could add to your program the display of the mem[] table address:

printf("A thread is continually updating all pages of global 1GB data (mem[]@%p). (pid : %d)\n", mem, getpid());

The size command displays the size of the data segment which is ~1GB:

$ gcc test.c -l pthread
$ size a.out
   text    data     bss     dec     hex filename
   2571 1073742504       16 1073745091  40000cc3    a.out

Execution which shows mem[]'s address at: 0x562c48575020

$ ./a.out 
A thread is continually updating all pages of global 1GB data (mem[]@0x562c48575020). (pid : 10029)
.............................................

Display of the map from another terminal where we can see the address of mem[] located in the zone 562c48575000-562c88576000:

$ cat /proc/`pidof a.out`/maps
562c48571000-562c48572000 r--p 00000000 08:05 9044419                    /home/xxx/a.out
562c48572000-562c48573000 r-xp 00001000 08:05 9044419                    /home/xxx/a.out
562c48573000-562c48574000 r--p 00002000 08:05 9044419                    /home/xxx/a.out
562c48574000-562c48575000 r--p 00002000 08:05 9044419                    /home/xxx/a.out
562c48575000-562c88576000 rw-p 00003000 08:05 9044419                    /home/xxx/a.out
562c89668000-562c89689000 rw-p 00000000 00:00 0                          [heap]
7f02946be000-7f02946bf000 ---p 00000000 00:00 0 
7f02946bf000-7f0294ebf000 rw-p 00000000 00:00 0 
7f0294ebf000-7f0294ee1000 r--p 00000000 08:05 6031519                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f0294ee1000-7f0295059000 r-xp 00022000 08:05 6031519                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f0295059000-7f02950a7000 r--p 0019a000 08:05 6031519                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f02950a7000-7f02950ab000 r--p 001e7000 08:05 6031519                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f02950ab000-7f02950ad000 rw-p 001eb000 08:05 6031519                    /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f02950ad000-7f02950b1000 rw-p 00000000 00:00 0 
7f02950b7000-7f02950bd000 r--p 00000000 08:05 6031549                    /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f02950bd000-7f02950ce000 r-xp 00006000 08:05 6031549                    /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f02950ce000-7f02950d4000 r--p 00017000 08:05 6031549                    /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f02950d4000-7f02950d5000 r--p 0001c000 08:05 6031549                    /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f02950d5000-7f02950d6000 rw-p 0001d000 08:05 6031549                    /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
7f02950d6000-7f02950da000 rw-p 00000000 00:00 0 
7f02950fc000-7f02950ff000 rw-p 00000000 00:00 0 
7f02950ff000-7f0295100000 r--p 00000000 08:05 6031511                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f0295100000-7f0295123000 r-xp 00001000 08:05 6031511                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f0295123000-7f029512b000 r--p 00024000 08:05 6031511                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f029512c000-7f029512d000 r--p 0002c000 08:05 6031511                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f029512d000-7f029512e000 rw-p 0002d000 08:05 6031511                    /usr/lib/x86_64-linux-gnu/ld-2.31.so
7f029512e000-7f029512f000 rw-p 00000000 00:00 0 
7f0295131000-7f0295133000 rw-p 00000000 00:00 0 
7ffcb340f000-7ffcb3430000 rw-p 00000000 00:00 0                          [stack]
7ffcb35ff000-7ffcb3603000 r--p 00000000 00:00 0                          [vvar]
7ffcb3603000-7ffcb3605000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]
  • Related