同CUP管理一样,内存管理也是操作系统最核心的功能之。内存主要用来存储系统和应用程序的指令,数据,缓存等。

内存映射

  • 通常说的8G内存指的是物理内存也成主存
  • 进程是不可以直接访问物理内存,只有cpu可以直接访问物理内存
  • 大多数的主存都是动态随机访问内存(DRAM)
  • linux 为每个进程分配一个独立的虚拟地址空间,并且是连续的。
  • 虚拟内存空间也被分为内核空间和用户空间。
  • 根据cpu指令可以处理数据的最大长度32位和64位
  • 32位cpu 最长寻址空间是4G 1G 系统空间 3G 用户空间
  • 64位cpu 最长寻址空间是17179869184G
    • 头128T 系统空间
    • 位128T 用户空间
    • 其他 其他空间
  • 每个进程都有用户态和内核态,所有的虚拟内存加起来一定大于物理内存,所以并不是所有虚拟内存都分配物理内存,只有那些实际使用的虚拟内存才分配物理内存,并且分配后的物理内存,是通过 内存映射 来管理的。
  • 设置1

  • MMU(Memory Management Unit)内存管理单元,用于存储页表
  • 每个进程都有一个对应的页表来做内存映射
  • 当虚拟地址在页表种查找不到地址时 缺页异常 进入内核空间分配物理内存,更新进程页表,最后返回用户空间,恢复进程运行。
  • MMU的最小单位是4KB称作
  • 由于页大小只有4KB,加入在32位系统中,就会有100多万的页表才能实现整个地址空间的映射。为了解决页表项过多的问题,linux提供两种机制
    • 多级页表:吧内存分成区块来管理,讲原来的映射关系改成区块索引和区块内的偏移。由于虚拟内存空间通常只用很少一部分,那么多级页表就只保存这些使用中的区块,这样就可以大大地减少页表的项数
    • 设置1
    • 大页:不明思议就是更大的内存块,常见2MB和1GB,多用于使用大量内存的进程上,比如Oracle,DPDK等

虚拟内存空间的分布

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

内存分配与回收

  • c语言使用malloc()方法分配内存
    • brk() 在c 标准库中当分配的内存小于128K默认使用brk(),当使用完成后并不会直接释放,而是缓存起来继续使用
      • 缺点:在系统繁忙时容易产生内存碎片
      • 优点:可以减少缺页异常的发生
    • mmap() 在大于128K使用mmap()分配内存
      • 缺点:频繁的分配内存,容易产生缺页异常
      • 优点:直接释放内存
  • 对于内存来说,如果只分配而不释放,就会造成内存泄漏,甚至会耗尽内存。所有应用程序使用完内存后,还需要调用free()或unmap(),来释放这些不用的内存。
  • 系统自身也不会任由应用程序的进程用完所有内存的,在发现内存紧张时,系统就会通过一系列机制来回收内存,比如下面这三种方式:
    • 回收缓存,比如使用LRU算法,回收最近使用最少的内存页
    • 回收不常访问的内存,把不常用的内存通过交换分区直接写到磁盘中(会使用交换分区Swap)
    • 杀死进程,内存紧张时系统还会通过OOM(Out of Memory),直接杀掉占用大量内存的进程。
      • 是一种内核保护机制
      • 使用oom_score记录每个进程的使用内存评分
      • 一个进程消耗的内存越大,oom_score就越大
      • 一个进程运行占用的CPU越多,oom_score就越小
      • 管理员可以手动设置oom_adj,oom_adj的范围[-17,15] 数值越大,表示进程越容易被OOM杀死,-17表示禁止OOM

如何查看内存使用情况

  • free 查看内存使用情况
    • total 是内存总大小
    • used 已使用的内存的大小,包好了共享内存
    • free 是未使用内存的大小
    • shared 是共享内存的大小
    • buff/cache 是缓存和缓冲区的大小
    • available 是进程可用内存的大小
  • top查看每个进程使用内存情况
    • VIRT 是进程虚拟内存的大小
    • RES 是常住内存的大小,进程实际使用物理内存的大小,不包含Swap和共享内存。
    • SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。
    • %MEM 是进程使用物理内存占系统内存的百分比

Buffer 和 Cache

  • 通常理解buffer是写入时合并写入,加快写入速度的
  • 通常理解cache是读取磁盘文件的页缓存,加快速度读取的

linux 文件系统

  • 在linux内所有一切皆文件
  • 文件分为好多类型(ls -l /dev):
    • -:普通文件
    • d: 目录
    • l:链接
    • d: 块文件
    • c: 字符串文件
    • s: socket文件
    • p: 管道文件
  • 磁盘会分区块,系统在每个区块上建立文件系统,在文件系统下创建目录,在目录中创建文件。
    • 普通文件就是目录中的文件,他的读写基于文件系统
    • 块文件,就是磁盘空间,他的读写会跳过文件系统
  • 对于以上的两种文件的读写,系统用了不同的优化方式
    • 普通文件:cache
    • 块文件:buffer
  • 以上就是cache和buffer的本质区别。