c - 为什么这个很小的 C 程序会占用这么多内存?
问题描述
int i = 0;
int main(){
while (true){
i = 1;
}
return 0;
}
上面的程序(用 gnu g++ 编译,没有额外的编译器标志)只是永远循环,似乎比它应该使用的内存更多(顶部的输出如下所示):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
9392 root 20 0 4376 788 728 R 100.0 0.0 2:32.65 a.out
我明白为什么 CPU 使用率为 100%,因为它在 while 循环中不断旋转。为什么 VIRT 是 4MB?为什么 SHR 是 728KB?我没有使用任何库。最后,也是最重要的,为什么要使用 788KB 来存储一个变量?剩余的 (4376-788)KB 在哪里/如何存储/使用?
解决方案
为什么 VIRT 是 4MB?为什么 SHR 是 728kB?我没有使用任何库。
这是不准确的。
让我们编译:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char buf[100];
snprintf(buf, sizeof buf, "pmap -x %u", (unsigned)getpid());
system(buf);
}
用命令gcc -o test -W{all,extra,error} -xc test.cc
。
并运行它:
$ ./test
7360: ./test
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 4 4 4 r-x-- test
0000000000600000 4 4 4 rw--- test
00007f1f4d96a000 1580 788 0 r-x-- libc-2.12.so
00007f1f4daf5000 2044 0 0 ----- libc-2.12.so
00007f1f4dcf4000 16 16 16 r---- libc-2.12.so
00007f1f4dcf8000 8 8 8 rw--- libc-2.12.so
00007f1f4dcfa000 16 8 8 rw--- [ anon ]
00007f1f4dcfe000 128 128 0 r-x-- ld-2.12.so
00007f1f4df0c000 12 12 12 rw--- [ anon ]
00007f1f4df1d000 4 4 4 rw--- [ anon ]
00007f1f4df1e000 4 4 4 r---- ld-2.12.so
00007f1f4df1f000 4 4 4 rw--- ld-2.12.so
00007f1f4df20000 4 4 4 rw--- [ anon ]
00007ffd4a872000 132 12 12 rw--- [ stack ]
00007ffd4a961000 12 0 0 r---- [ anon ]
00007ffd4a964000 8 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------ ------ ------
total kB 3984 1000 80
(如果您在pmap -x
输出中看到重复的行,这是旧版本中的错误)。
所以,它使用
libc.so
- C 标准库。ld.so
- 动态链接器。
RSS 的 1000kB 被占用:
- 920kB 是您的可执行文件 (4kB) 和共享库(带
r-x--
模式的页面)的可执行代码 - 12kB 是堆栈(标记为
[ stack ]
)。 - 标记为模式的页面
[ anon ]
是来自可执行库和共享库的部分的rw---
堆和 0 初始化数据,具有静态存储持续时间。.bss
- 其余的是只读和非 0 初始化数据,具有来自可执行文件和共享库的 (mode) 部分的静态存储
.data
持续.rodata
时间r----
。
推荐阅读
- firebase - 为什么我的用于 Firebase 身份验证的 kotlin 代码不起作用?
- r - 在我的数据框中填充一列,以其他列为条件,使用第三列的值
- c++ - 分配两个双打保证产生相同的位集模式?
- python - 如何用逗号格式化浮点数作为 f 字符串中的小数分隔符?
- c++ - 如何在 C++ 中使用变量执行 sql_query?
- r - 如何使用给定数据点的 R 中的广义线性建模进行预测
- spring-integration - 使用 Header Enricher/SpEL 解析连接 ID 并在 Map 中查找
- sql - 相同 ID 的哈希后解密不起作用
- tfs - 是否可以将代码从 Bitbucket 迁移到具有历史记录的 TFS 2018.3(本地)?
- mysql - 从分子框架中的mysql数据库的find方法中获取选择字段