我创建了以下函数来检查静态局部变量的内存使用情况,并期望数组占用大约5MB的内存,但是当我运行它时,进程的物理内存使用仅为0.2MB,而当我运行时实际上为数组中的每个元素设置了一个值。
我的理解是,当我第一次初始化数组时,无论数组中元素的值如何,都将为其分配内存。因为我能够访问数组的第一个元素和最后一个元素,内存在哪一个元素之间?
void func() {
static char a[5000000];
a[0] = 'a';
a[4999999] = 'a';
cin >> a;
}
int main(int argc, char const *argv[]) {
func();
return 0;
}
答案 0 :(得分:1)
这是由于惰性内存分配或zero fill on demand,如下所述。
zero initialization中cppreference对此进行了解释:
在以下情况下执行零初始化:
1对于每个具有静态或线程本地存储持续时间的命名变量,该变量在进行任何其他初始化之前均不进行常量初始化(自C ++ 14起)。
因此该变量符合条件。 零初始化是什么意思:
零初始化的影响是:
- 如果T是标量类型,则对象的初始值为明确转换为T的积分常数零。
- [...]如果T为数组类型,则每个元素都将初始化为零
作为一种优化,大多数现代系统甚至没有为零个初始化的全局/静态变量分配任何内存,这就是为什么数组大小不影响内存使用的原因。相反,可执行文件带有一个标记,上面写着:“这里应该是零值”,仅此而已。程序加载时,所有地址都映射到包含零的物理RAM的一个小型共享只读块。
几个虚拟地址可以通过CPU中称为“ Memory management unit”(MMU)的硬件映射到同一内存。当代码尝试写入该范围内的地址时,MMU会通知操作系统(OS)某人正在写入一个只读内存块,然后操作系统才分配内存。