为什么GCC/Ubuntu下只读访问全局数组的内存占用远低于修改访问?
核心原因是Linux操作系统的虚拟内存优化机制,具体逻辑如下:
- 你声明的未初始化全局大数组
buffer属于程序的BSS段,GCC编译时不会在二进制可执行文件中为其分配实际存储空间,仅会记录该段的总大小。 - 程序启动加载时,内核只会为该数组分配连续的虚拟地址范围,不会直接分配对应的物理内存页。
- 当你仅对数组做只读访问时,内核会将所有数组对应的虚拟内存页全部映射到系统全局共享的只读零页:这是系统预先生成的、内容全为0的物理页,所有初始值为0的内存区域读取时都会共用这个页,无需额外分配物理内存。因此整个程序的物理内存占用只有程序自身运行的基础开销(代码段、栈、堆等),总大小仅188KiB符合预期。
- 当你修改数组元素时,会触发写时复制(COW)机制:内核会为每个被写入的虚拟内存页单独分配对应的物理内存页,256MiB的数组刚好需要分配256MiB的物理内存,加上基础开销后总占用就是256.1MiB。
针对你补充的xxd使用场景的额外说明:
通过xxd -i生成的是显式初始化的全局数组,该数组会被放到程序的数据段而非BSS段,编译时会把所有数组内容直接写到可执行文件中,加载时内核会直接为其分配对应大小的物理内存并写入初始化值,不会触发零页优化,无论后续是读还是写,都会占用和数组大小匹配的物理内存。
内容的提问来源于stack exchange,提问作者Amir
相关产品推荐
相关产品推荐

