Linux C 编程 - 虚拟内存管理

操作系统利用体系结构提供的VA到PA的转换机制实现虚拟内存管理,下面可以进一步来理解虚拟内存管理:

# psPID   USER     TIME   COMMAND    1 root       0:14 {linuxrc} init    2 root       0:00 [kthreadd]    3 root       0:00 [ksoftirqd/0]    4 root       0:00 [kworker/0:0]    5 root       0:00 [kworker/0:0H]    7 root       0:47 [rcu_preempt]    8 root       0:00 [rcu_sched]    9 root       0:00 [rcu_bh]   10 root       0:00 [migration/0]   11 root       0:00 [watchdog/0]   12 root       0:00 [watchdog/1]   13 root       0:00 [migration/1]   14 root       0:00 [ksoftirqd/1]   16 root       0:00 [kworker/1:0H]   17 root       0:00 [kdevtmpfs]  983 root       0:02 mc_server

用ps命令查看当前终端下的进程,得知mc_server进程的id是983,然后使用car /proc/983/maps 命令查看它的虚拟地址空间。/proc 目录中的文件并不是真正的磁盘文件,而是由内核虚拟出来的文件系统,当前系统中运行的每个进程在/proc 文件都有一个子目录,目录名就是进程的id,查看目录下的文件可以得到该进程的相关信息。

# cat /proc/983/maps00400000-00401000 r-xp 00000000 1f:05 384                                /usr/bin/mc_server00410000-00411000 rw-p 00000000 1f:05 384                                /usr/bin/mc_server16ce7000-17103000 rw-p 00000000 00:00 0                                  [heap]7f8c7cb000-7f8c7d1000 r-xp 00000000 1f:05 208                            /lib/librt-2.23.so7f8c7d1000-7f8c7e0000 ---p 00006000 1f:05 208                            /lib/librt-2.23.so7f8c7e0000-7f8c7e1000 r--p 00005000 1f:05 208                            /lib/librt-2.23.so7f8c7e1000-7f8c7e2000 rw-p 00006000 1f:05 208                            /lib/librt-2.23.so7f8c7e2000-7f8c90d000 r-xp 00000000 1f:05 187                            /lib/libc-2.23.so7f8c90d000-7f8c91c000 ---p 0012b000 1f:05 187                            /lib/libc-2.23.so7f8c91c000-7f8c920000 r--p 0012a000 1f:05 187                            /lib/libc-2.23.so7f8c920000-7f8c922000 rw-p 0012e000 1f:05 187                            /lib/libc-2.23.so7f8c922000-7f8c926000 rw-p 00000000 00:00 0 7f8c926000-7f8c93a000 r-xp 00000000 1f:05 463                            /usr/lib/libcncrDriver.so7f8c93a000-7f8c949000 ---p 00014000 1f:05 463                            /usr/lib/libcncrDriver.so7f8c949000-7f8c94a000 rw-p 00013000 1f:05 463                            /usr/lib/libcncrDriver.so7f8c94a000-7f8cb86000 rw-p 00000000 00:00 0 7f8cb86000-7f8cb95000 r-xp 00000000 1f:05 494                            /usr/lib/libibcUtilsMc.so7f8cb95000-7f8cba5000 ---p 0000f000 1f:05 494                            /usr/lib/libibcUtilsMc.so7f8cba5000-7f8cba8000 rw-p 0000f000 1f:05 494                            /usr/lib/libibcUtilsMc.so7f8cba8000-7f8cbaa000 rw-p 00000000 00:00 0 7f8cbaa000-7f8cbc0000 r-xp 00000000 1f:05 204                            /lib/libpthread-2.23.so7f8cbc0000-7f8cbd0000 ---p 00016000 1f:05 204                            /lib/libpthread-2.23.so7f8cbd0000-7f8cbd1000 r--p 00016000 1f:05 204                            /lib/libpthread-2.23.so7f8cbd1000-7f8cbd2000 rw-p 00017000 1f:05 204                            /lib/libpthread-2.23.so7f8cbd2000-7f8cbd6000 rw-p 00000000 00:00 0 7f8cbd6000-7f8cbe0000 r-xp 00000000 1f:05 462                            /usr/lib/libboardConfigOPMc.so7f8cbe0000-7f8cbef000 ---p 0000a000 1f:05 462                            /usr/lib/libboardConfigOPMc.so7f8cbef000-7f8cbf0000 rw-p 00009000 1f:05 462                            /usr/lib/libboardConfigOPMc.so7f8cbf0000-7f8cc18000 rw-p 00000000 00:00 0 7f8cc18000-7f8cc35000 r-xp 00000000 1f:05 179                            /lib/ld-2.23.so7f8cc3e000-7f8cc42000 rw-p 00000000 00:00 0 7f8cc42000-7f8cc43000 r--p 00000000 00:00 0                              [vvar]7f8cc43000-7f8cc44000 r-xp 00000000 00:00 0                              [vdso]7f8cc44000-7f8cc45000 r--p 0001c000 1f:05 179                            /lib/ld-2.23.so7f8cc45000-7f8cc47000 rw-p 0001d000 1f:05 179                            /lib/ld-2.23.so7fdba5c000-7fdba86000 rw-p 00000000 00:00 0                              [stack]

x86 平台的虚拟地址空间是0x0000 0000 0xffff ffff, 大致上前3GB(0x0000 0000 00xbfff ffff)是用户空间,后1GB(0xC000 0000 ~ 0xffff ffff)是内核空间。

0x00400000-0x00401000地址段,访问权限是 r-x, 表示Text Segment, 包含.text段,.rodata段,.plt段等。

0x00410000-0x00411000地址段,访问权限为r-w, 表示Data Segment,包含.data段,.bss段等。

0x16ce7000-0x17103000不是从磁盘文件加载到内存的,这段空间称为堆(Heap), malloc函数动态分配内存是在这里分配的。

从0x7f8c7cb000开始是共享库的映射空间,每个共享库也分为几个Segment,每个Segment有不同的访问权限。从堆空间的结束地址0x17103000到共享库映射空间的起始地址0x16ce7000之间有很大的地址空洞,在地址分配内存时堆空间是可以向高地址增长的。堆空间的地址上限称为Break, 堆空间要向高地址增长就要抬高Break, 映射新的虚拟内存空间到物理内存,这是通过系统调用brk实现的。malloc函数也是调用break向内核请求分配内存的。

0x7fdba5c000-0x7fdba86000是栈空间,其中高地址的部分保存着进程的环境变量和命令行参数,低地址的部分保存函数栈帧,栈空间是向低地址增长的,但显然没有堆空间那么大的可供增长的余地,因为实际的应用程序动态分配大量的并不少见,但是函数调用有很多局部变量的非常少见。栈空间是可能用尽的,并且比堆空间更容易用尽,用尽栈空间最终导致段错误。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章