内存性能篇(一):内存是怎么工作的

###linux内存工作原理在这里插入图片描述

###内存映射

内存主要是用来存储系统和应用程序的指令、数据、缓存等
DRAM 动态随机访问内存
linux内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的,这样进程可以很方便的访问内存,确切的说是访问虚拟内存
虚拟地址空间内部又被分为:

  1. 内核空间
  2. 用户空间
    在这里插入图片描述
    只有实际使用的虚拟内存才会分配物理内存,并且分配后的物理内存,是通过内存映射来管理的
    内存映射:就是将虚拟内存地址映射到物理内存地址
    内核为每个进程都维护了一张页表,记录虚拟地址与物理地址的映射关系。页表实际上是存储在CPU的内存管理单元MMU中,这样正常情况下,处理器就可以直接通过硬件,找出要访问的内存
    在这里插入图片描述
    缺页异常:当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入内核空间分配物理内存,更新进程页表,最后在返回用户空间,恢复进程的运行
    TLB:其实就是MMU中页表的高速缓存
    MMU并不以字节为单位来管理内存,而是规定一个内存映射的最小单位,也就是页,通常是4KB大小

Linux提供了两种机制,解决页表项过多的问题

  1. 多级页表:多级页表就是把内存分成区块来管理,将原来的映射关系改成区块索引和区块内的偏移,由于虚拟内存空间通常只用了很少一部分,那么,多级页表就只保存这些使用中的区块,这样就可以大大地减少页表的项数
  2. 大页 Huge:就是比普通页更大的内存块,常见的大小有 2MB 和 1GB。大页通常用在使用大量内存的进程上,比如 Oracle、DPDK 等

在这里插入图片描述

###虚拟内存空间分布

32位系统用户内存空间:

  1. 只读段 包括代码和常量等
  2. 数据段 包括全局变量等
  3. 堆 包括动态分配的内存,从低地址开始向上增长
  4. 文件映射段 包括动态库、共享内存等,从高地址开始向下增长
  5. 栈 包括局部变量和函数调用的上下文等,栈的大小是固定的,一般是8MB

在这里插入图片描述

###内存的分配与回收

malloc()是C标准库提供的内存分配函数,对应到系统调用上,有两种是实现方式:

  1. brk() 对于小块内存(小于128K),使用brk()来分配,也就是通过移动堆顶的位置来分配内存。这些内存释放后不会立即归还系统,而是被缓存起来,这样就可以重复使用
  2. mmap() 对于大块内存(大于128K),直接使用内存映射mmap()来分配,也就是在文件映射段找一块空闲内存分配出去。这种方式分配的内存,会在释放时直接归还系统
    内存紧张时,系统会调用free()或者unmap()来释放不用的内存
    系统回收内存的三种方式:
  3. 回收缓存 比如使用LRU(Least Recently Used)算法,回收最近使用最少的内存页面
  4. 回收不常访问的内存,把不常用的内存通过交换分区直接写入到磁盘中
  5. 杀死进程,内存紧张时,系统通过OOM,直接杀掉占用大量内存的进程

OOM(Out of Memory):是内核的一种保护机制。它监控进程的内存使用情况,并且使用 oom_score 为每个进程的内存使用情况进行评分

  1. 一个进程消耗的内存越大,oom_score 就越大
  2. 一个进程运行占用的 CPU 越多,oom_score 就越小
  3. 为了实际工作的需要,管理员可以通过 /proc 文件系统,手动设置进程的 oom_adj ,从而调整进程的 oom_score
  4. oom_adj 的范围是 [-17, 15],数值越大,表示进程越容易被 OOM 杀死;数值越小,表示进程越不容易被 OOM 杀死,其中 -17 表示禁止 OOM
### 把 sshd 进程的 oom_adj 调小为 -16
echo -16 > /proc/$(pidof sshd)/oom_adj

###查看内存的使用情况

free查看内存使用情况:

  1. total 是总内存大小
  2. used 是已使用内存的大小,包含了共享内存
  3. free 是未使用内存的大小
  4. shared 是共享内存的大小
  5. buff/cache 是缓存和缓冲区的大小
  6. available 是新进程可用内存的大小
    a. available 不仅包含未使用内存,还包括了可回收的缓存,所以一般会比未使用内存更大。不过,并不是所有缓存都可以回收,因为有些缓存可能正在使用中

top命令输出的参数说明:

  1. VIRT 进程的虚拟内存的大小,只要进程申请过的内存,即便还没有真正分配物理内存,也会计算在内
  2. RES 常驻内存的大小,也就是进程实际使用物理内存的大小,但不包括swap和共享内存
  3. SHR 共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等
    a. 共享内存 SHR 并不一定是共享的,比方说,程序的代码段、非共享的动态链接库,也都算在 SHR 里。当然,SHR 也包括了进程间真正共享的内存。所以在计算多个进程的内存使用时,不要把所有进程的 SHR 直接相加得出结果
  4. %MEM 进程使用物理内存占用系统内存的百分比
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值