linux内存占用高但看不到进程_Linux 进程虚拟内存

进程虚拟内存

虚拟地址空间

各个进程的虚拟地址空间起始于 0,一直到 TASK_SIZE - 1,其上是内核地址空间。在 IA-32 系统上地址空间的范围是 4GB,按照默认比例 3:1 来划分的话,内核分配 1GB,各个用户进程可用的部分为 3GB。用户程序只能访问整个地址空间的下半部分,不能访问内核部分,同时用户进程也不能操作另一个进程的地址空间(除非共享内存),因为后者的地址空间不可见。

进程虚拟地址空间由多个不同长度的段组成,用于不同的目的,必须分别处理。例如大多数情况下,不许修改 text 段(代码段),但是可以执行它。另外,必须可以修改映射到地址空间的文本文件内容,但是不可以执行它。进程虚拟地址空间中一般都包含如下不同的段:

- 当前运行代码的二进制代码。该代码通常称之为 text,所处的虚拟内存区域称之为 text 段。ELF(Executable and Linkable Format)二进制文件映射到地址空间后,该区域长度不变,边界由 start_code 和 end_code 标记。

- 程序使用的动态库的代码。

- 存储全局变量和动态产生的数据的堆。start_brk 标识了堆的起始位置,其长度在运行阶段会发生变化。

- 用于保存局部变量和实现函数过程调用的栈。

- 环境变量和命令行参数的段。由 arg_start,arg_end,env_start,env_end 标识。

- 将文件内容映射到虚拟地址空间中的内存映射。

在进程启动时可以指定 PF_RANDOMIZE,如果指定了该标志,则内核不会为栈和内存映射选择固定的起始点,而是每次都在一个小范围内随机,这有助于防止缓冲区溢出攻击。

e0165e1814177fa019cf8d224b278610.png

每个体系结构都制定了一个特殊的起始地址,IA-32 起始于 0x08048000,在 text 段的起始地址与最低的可用地址之间有大约 128 MB 的间距,用于捕捉 NULL 指针。其他体系结构也类似,堆紧随着 text 开始,向上增长。栈起始于 STACK_TOP,如果设置了 PF_RANDOMIZE,则起始位置会有一个小的随机量。大多数体系结构中 STACK_TOP 等于 TASK_SIZE,即用户地址空间的最高可用地址。进程的参数列表和环境变量都是栈的初始数据。在 2.6.7 之后,栈的最大长度遭到限制,因此内存映射区域从栈的下方开始(包含一个安全带),自顶向下拓展,mmap 区域和堆相对拓展,直至耗尽地址空间中的剩余区域。

地址转换

在古老的 x86 体系处理器上,刚开始只有 20 根地址线,寻址寄存器是 16 位,我们知道 16 位的寄存器可以访问 64K 的地址空间,如果程序要想访问大于 64K 的内存,就需要把内存分段,每段 64K,用段地址 + 偏移量的方式来访问,这样使 20 根地址线全用上,最大的寻址空间就可以到 1M 字节,这在当时已经是非常大的内存空间了。在这种段式内存管理机制中,访内指令给出的地址 (操作数) 叫逻辑地址,也叫相对地址,也就是是机器语言指令中,用来指定一个操作数或是一条指令的地址。一个逻辑地址由两部分组成,段标识符: 段内偏移量。段标识符是由一个 16 位长的字段组成,称为段选择符。其中前 13 位是个索引号,后面 3 位包含一些硬件细节。

b630f5b668d331466cd048b3337a9cb7.png

不过在现代的 CPU 架构中,段式内存管理显然有些多余,因为现代 CPU 的寻址寄存器已经能够覆盖完整的虚拟地址空间,但是为了兼容老旧的设备,Linux 还需要保存这个段式管理机制,但是对于现代 CPU 架构,Linux 会有一个伪段式内存管理机制,这个伪造的段内存管理器很简单,输入的段地址会原封不动的输出作为线性地址(虚拟地址)。

我们知道页表用于建立用户进程的虚拟地址空间(也就是前面说的线性地址)和系统物理内存(内存、页帧)之间的关联。前面结构主要用来描述内存的结构(划分为结点和内存域),同时指定了其中包含的页帧的数量和状态(使用中或空闲)。页表用于向每个进程提供一致的虚拟地址空间。应用程序看到的地址空间是一个连续的内存区,而页表将连续的虚拟地址空间映射到不连续的物理地址空间。该表也将虚拟内存页映射到物理内存,因而支持共享内存的实现(几个进程同时共享的内存),还可以在不额外增加物理内存的情况下,将页换出到块设备来增加有效的可用内存空间。

30b076291e57af818c813b179e37a425.png

- pgd用于全局页目录项。

- pud用于上层页目录项。

- pmd用于中间页目录项。

- pte用于直接页表项。

- offset 用于页内偏移。

内核内存管理总是假定使用四级页表,而这在 IA-32 系统中是不对的,因为它只使用两级分页系统。因此,三四级页表必须在体系结构的代码中进行模拟。

内存映射

由于所有用户进程总的虚拟地址空间比可用的物理内存大得

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值