简体   繁体   中英

Why global array (initialized) in C is not totally counted as PSS

envirenment: gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 3.16.0-30-generic #40~14.04.1-Ubuntu SMP Thu Jan 15 17:45:15 UTC 2015 i686 i686 i686 GNU

C code a2.c: has a 40MB global array, and each items are assigmented.

int b[10000000];//40M global array
void main() {
  int i = 0;
  for(i = 0; i<10000000; i++) {b[i]=i;}
  while(1);
}

and I build like gcc -o a2 a2.c

When I run this code and see the smap file cat /proc/25739/smaps , the content are as follows

08048000-08049000 r-xp 00000000 08:11 46930087   /home/jzd/test/a2
Size:                  4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         4 kB
Private_Dirty:         0 kB
Referenced:            4 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
VmFlags: rd ex mr mw me dw
//here I hide some sections 
0804b000-0a670000 rw-p 00000000 00:00 0
Size:              39060 kB
Rss:               39060 kB // the RSS is the global array's size
Pss:                2196 kB // the array is only used by the program
                            // why it's pss is not equal with rss
Shared_Clean:          0 kB // all shared size is 0
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:     39060 kB
Referenced:        39060 kB
Anonymous:         39060 kB
AnonHugePages:     36864 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
VmFlags: rd wr mr mw me ac
//here I hide other sections

Why does that happen?

You have the support for transparent huge pages (THP) enabled and your executable's BSS is backed by huge pages:

0804b000-0a670000 rw-p 00000000 00:00 0
Size:              39060 kB
Rss:               39060 kB
Pss:                2196 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:     39060 kB
Referenced:        39060 kB
Anonymous:         39060 kB
AnonHugePages:     36864 kB <------
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB
VmFlags: rd wr mr mw me ac

If you look closely, the reported Pss value of 2196 KiB is exactly the amount of anonymous memory mappings backed by regular 4 KiB pages, ie the difference between Anonymous and AnonHugePages .

My guess is that the accounting of THP in PSS is broken in 3.16.0-30-generic. Between your kernel version and the version of @Evan's kernel, there are several commits affecting the part of the Linux kernel that generates the contents of the smaps file ( fs/proc/task_mmu.c ), more specifically this change between 3.18 and 3.19 likely fixed things.

I'm not sure why you are seeing that, I ran your test program and get a different result, in line with what you were expecting:

00602000-02c27000 rw-p 00000000 00:00 0 
Size:              39060 kB
Rss:               39060 kB
Pss:               39060 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:     39060 kB
Referenced:        38824 kB
Anonymous:         39060 kB
AnonHugePages:      8192 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Locked:                0 kB

My kernel version is 3.19.0-30-generic #34-Ubuntu SMP . Are you sure that you are running the program exactly as you posted it? It is also possible that the kernel memory reporting changed at some point, or that this behavior depends on how the kernel is built.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM