Linux性能优化实战 15:内存映射、虚拟内存空间分布、内存分配与回收 和 查看内存使用

本文深入解析Linux内存管理机制,涵盖虚拟内存与物理内存映射、内存分配与回收策略,及如何利用free和top命令监测内存状态。理解内存段划分、页表作用与内存分配函数的不同实现,掌握内存管理核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、内存映射 **

1. 通常所说的内存容量,指的是物理内存。进程是不能直接访问物理内存的。

     Linux 内核给每个进程都提供一个独立的虚拟地址空间,这个地址空间是连续的。(也就是虚拟内存)

2. 虚拟地址空间的内部又被分为内核空间和用户空间。

    

    32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间。

    进程在用户态时,只能访问用户空间内存;只有进入内核态后,才可以访问内核空间内存。

3. 内存映射,其实就是将虚拟内存地址映射到物理内存地址。

    

(1) 页表实际上存储在 CPU 的内存管理单元 MMU 中。

(2) 不是所有的虚拟内存都会分配物理内存,当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常

(3) 缺页异常时,需要进入内核空间分配物理内存,更新页表,再返回用户空间。

(4) MMU规定了一个内存映射的最小单位,4K。 所以4K的数据可以集中在一个页面中,可以访问加速。

二、虚拟内存空间分布 **

1. 用户空间内存,其实又被分成了多个不同的段

(1) 只读段,包括代码和常量等。

(2) 数据段,包括全局变量等。

(3) 堆,包括动态分配的内存。

(4) 文件映射段,包括动态库共享内存等。

(5) 栈,包括局部变量和函数调用的上下文等。

三、内存分配与回收 *

1. malloc() 是 C 标准库提供的内存分配函数,有两种实现方式,即 brk() 和 mmap()。

(1) brk(): 小块内存(小于 128K)时使用。

                在堆段位置, 释放后并不会立刻归还系统,而是被缓存起来,可以重复使用,提高内存访问效率。

(2) mmap():大块内存(大于 128K)时使用。

                 在文件映射段位置,找一块空闲内存分配出去。

2. 系统发现内存紧张时,会通过三种方式来回收内存:

(1) 回收缓存 LRU

     使用 LRU(Least Recently Used)算法,回收最近使用最少的内存页面.

(2) 回收不常访问的内存 SWAP

     把不常用的内存通过交换分区(Swap)直接写到磁盘中,当进程访问这些内存时,再从磁盘读取这些数据到内存中.

(3) 杀死进程 OOM

     通过 OOM(Out of Memory),直接杀掉占用大量内存的进程。

     OOM使用 oom_score 为每个进程的内存使用情况进行评分:

     一个进程消耗的内存越大,oom_score 就越大;

     一个进程运行占用的 CPU 越多,oom_score 就越小...

      oom_score 越大,越容易被 OOM 杀死。值范围[-17,15]

      防止被OOM杀死: echo -16 > /proc/$(pidof sshd)/oom_adj

四、如何查看内存使用情况 **

1. free命令:  (有些系统需要 free -a )

     

    total  :总内存大小;

    used :已使用内存的大小,包含了共享内存;

    free   :未使用内存的大小;

    shared : 共享内存的大小;

    buff/cache : 是缓存和缓冲区的大小;

    available :剩余可用内存的大小。

                      不仅包含未使用内存,还包括了可回收的缓存,所以一般会比未使用内存更大。

2. top命令:  (查看具体的进程的使用内存状况)

 VIRT : 虚拟内存的大小。

 RES : 常驻内存的大小。 实际使用的物理内存大小,但不包括 Swap 和共享内存。

 SHR : 共享内存的大小。比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。

 %MEM:进程使用物理内存占系统总内存的百分比。

(1) 虚拟内存并不会全部分配物理内存,虚拟内存都比常驻内存大得多。

(2) 共享内存 SHR 并不一定是共享的,比方说,程序的代码段、非共享的动态链接库。所以计算时不能直接相加。

五、其他一些补充 **

1. 程序启动后,分配的虚拟内存大小不是固定的,堆段和‌内存映射段遇到预分配空间不足情况时,是会动态扩展的。

2. 虚拟内存地址,段内大致连续,段间不连续。各段之间存在地址间隙或保护页,整体虚拟地址空间不连续。 文件映射段段内也不连续,会动态增加映射区域‌。

3. ‌程序启动时分配的虚拟内存‌ = 静态段(代码/数据/BSS) + 堆预留空间 + 栈 + 动态库映射 + 对齐间隙。

4. 实际物理内存‌ 远小于虚拟内存,不立刻分配,到使用时先触发缺页异常,然后才分配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值