You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ELF可执行文件.data段数组访问无Major页故障的原因问询

问题:为何访问.data段数组未触发Major页故障?

我预期以下程序在访问数组x的部分内容时会触发Major页故障——注意该数组不在.bss段而在.data段。

#include <unistd.h>

#define C (256*1024*1024)

char x[C] = { 1 };

int main(void)
{
   char c;
   read (STDIN_FILENO, &c, 1);
   for (int i = 1024; i < C; i += 1024) {
     x[i] = x[i] - 1;
     x[i - 1024] = x[i];
   }
}

编译后可见数组x确实在可执行文件中:

$ gcc a.c; ls -l a.out
-rwxr-xr-x. 1 mcadilha domain users 257M Jan 20 20:49 a.out

但/usr/bin/time的报告与预期不符:未进入主循环时,Major页故障为0,仅少量Minor页故障;进入主循环后,Major页故障仍为0,Minor页故障为65593。我尝试将x填充为随机值,结果无变化。请问:为何未产生任何Major页故障?

原因分析

  • Major页故障的本质:Major页故障只有在需要从磁盘直接读取数据到物理内存时才会触发;而Minor页故障是指数据已经存在于系统的页缓存中,只需建立虚拟内存到物理内存的映射,不需要额外的磁盘IO。
  • 可执行文件的映射逻辑:当程序加载时,操作系统会把可执行文件的.data段映射到进程虚拟地址空间,但不会立即加载所有数据到物理内存。不过,操作系统会维护页缓存——可执行文件本身存储在磁盘上,系统在处理程序加载请求时,会把文件内容预读到页缓存里,或者在第一次访问时先从磁盘读入缓存。
  • 你的程序的实际执行流程:当主循环访问数组x的页面时,这些页面的数据已经在页缓存中存在了,操作系统只需要完成虚拟页到缓存物理页的映射,所以只会触发Minor页故障,不会产生Major页故障。
  • 填充随机值无影响的原因:不管数组初始化内容是固定值还是随机值,只要可执行文件生成后被正确映射,其内容都会被操作系统纳入页缓存管理,后续访问时依然不需要从磁盘重新读取,自然不会出现Major页故障。

内容的提问来源于stack exchange,提问作者Michaël

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:32:06