为什么C中的全局数组(初始化)不完全计为PSS

时间:2015-11-12 05:40:14

标签: c linux shared-memory memory-mapped-files

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代码a2.c:具有40MB的全局数组,并且每个项目都已分配。

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

我的构建方式与gcc -o a2 a2.c

类似

当我运行此代码并查看smap文件cat /proc/25739/smaps时,内容如下

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

为什么会这样?

2 个答案:

答案 0 :(得分:1)

您支持启用透明大页面(THP),并且您的可执行文件BSS由大页面支持:

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

如果仔细观察,报告的Pss值为2196 KiB正好是由常规4 KiB页面支持的匿名内存映射量,即AnonymousAnonHugePages之间的差异。

我的猜测是,PSS中THP的核算在3.16.0-30-通用中被打破。在你的内核版本和@Evan内核的版本之间,有几个提交会影响Linux内核中生成smaps文件(fs/proc/task_mmu.c)内容的部分,更具体地来说,这个改变between 3.18 and 3.19可能固定的东西。

答案 1 :(得分:0)

我不确定你为什么会看到这个,我运行你的测试程序并得到一个不同的结果,符合你的期望:

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

我的内核版本是3.19.0-30-generic #34-Ubuntu SMP。你确定你运行的程序与你发布的完全一样吗?内核内存报告也可能在某些时候发生了变化,或者这种行为取决于内核的构建方式。