性能·内存 / 命令文档

Linux内存映射

$ memory 7 个章节 Linux 命令详解

概述

深入理解虚拟地址到物理地址的转换机制

什么是内存映射?

内存映射(Memory Mapping)是Linux系统中最核心的概念之一。它是虚拟地址空间与物理内存之间的桥梁,负责将程序使用的虚拟内存地址 映射为 实际的物理内存地址。

核心概念: 每个进程都有自己的虚拟地址空间,通过页表(Page Table)和MMU(内存管理单元)将虚拟地址映射到物理地址。这种机制提供了内存保护、地址空间隔离和高效的内存管理。

虚拟地址空间

栈区 (Stack)

堆区 (Heap)

代码段 (Text)

数据段 (Data)

MMU

物理内存

Frame 1

Frame 2

Frame 3

Frame 4

页表结构详解

页表是内存映射的核心数据结构,它记录了虚拟页面到物理页面的映射关系以及相关的权限信息。

页表项 (Page Table Entry) 示例:

虚拟地址

物理地址

权限

标志位

0x7fff1234

0x1a2b3000

RW-

Present, User, Writable

0x7f8b4567

0x2c4d5000

RWX

Present, User, Executable

0x55555554

0x3e6f7000

R-X

Present, User, Execute-only

0x55555558

0x4a8b9000

RW-

Present, User, Dirty

1. 地址分解 虚拟地址分解为页号和偏移量

2. 页表查找 通过页号查找页表项

3. 权限检查 验证访问权限和有效性

4. 地址转换 组合物理页号和偏移量

匿名映射 (Anonymous Mapping)

匿名映射不与任何文件关联,主要用于分配堆内存、栈空间等。

// 分配8KB匿名内存

void *ptr = mmap(

NULL, // 让内核选择地址

8192, // 大小: 8KB

PROT_READ | PROT_WRITE, // 可读写

MAP_PRIVATE | MAP_ANONYMOUS, // 私有匿名

-1, // 无文件描述符

0 // 无偏移量

);

堆内存分配

malloc()内部使用匿名映射分配大块内存

栈空间扩展

当栈空间不足时自动扩展

文件映射 (File Mapping)

将文件内容直接映射到虚拟地址空间,实现文件的内存访问。

// 将文件映射到内存

int fd = open("data.txt", O_RDWR);

struct stat sb;

fstat(fd, &sb);

char *file_data = mmap(

NULL, // 地址由内核选择

sb.st_size, // 文件大小

PROT_READ | PROT_WRITE, // 读写权限

MAP_SHARED, // 共享映射

fd, // 文件描述符

0 // 从文件开头映射

);

高效文件IO

避免read/write系统调用开销

延迟加载

按需从磁盘加载文件内容

共享映射 (Shared Mapping)

多个进程可以共享同一块物理内存区域,实现进程间通信。

// 创建共享内存段

int shm_fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);

ftruncate(shm_fd, 4096);

void *shared_mem = mmap(

NULL,

4096,

PROT_READ | PROT_WRITE,

MAP_SHARED, // 关键:共享映射

shm_fd,

);

进程间通信

高效的IPC机制

内存共享

多个进程共享同一物理页面

私有映射 (Private Mapping)

采用写时复制(COW)机制,每个进程拥有独立的内存副本。

// 私有文件映射

void *private_data = mmap(

NULL,

同分类 · 其他命令文档