course2610_lab18 内存性能优化之初步体验

Linux内核给每个进程提供了一个独立的连续虚拟地址空间( 注意独立代表: 可以将进程内存隔离)。

每个进程的虚拟地址分为内核空间和用户空间。

但内核空间,其实关联的都是相同的物理内存。
内核态可以访问内核空间内存。

进程用户态只能访问用户空间内存;

1. 内存映射

1.1. 什么是内存映射:

内存映射就是将虚拟内存地址映射到物理内存地址,内核为每个进程都维护了一张页表,记录映射关系。

在这里插入图片描述

1.2 页表的概念

页表实际存储在CPU的内存管理单元MMU中,页表还有一个缓冲TLB(Translation Lookaside Buffer,转译后备缓冲器)。

页的大小为4KB,为了解决页过多,
Linux提供了两种机制多级页表和大页(HugePage)。

  • 多级页表: 就是把内存分成区块来管理,将原来的映射关系改成区块索引和区块内的偏移,这样可以大大减少页表的项数。(其实也可以直接映射正使用的页,但这会导致页不连续,不能使用偏移量查找)

Linux使用四级页表管理内存页。
在这里插入图片描述

  • 大页:就是比普通页更大的内存块。

当访问虚拟地址在页表中找不到时,会产生缺页异常,进入内核空间分配物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。

2. 虚拟内存空间分布

在这里插入图片描述
上图为32位系统虚拟内存空间分布。
除内核空间外,

用户空间内存,从顶层到底分别为:

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

使用 C 标准库的 malloc() 或者 mmap() ,就可以分别在堆和文件映射段动态分配内存。

3. 内存分配与回收

3.1 内存分配

C 标准库采用 malloc() 分配内存,有两种实现方式,brk mmap()

  1. brk() 分配小内存(小于 128K),通过移动堆顶的位置实现,释放后不会立刻归还内存,而是被缓存起来,供重复使用。

  2. mmap() 分配大内存(大于 128K),在文件映射段找一块空闲内存分配出去,释放后直接归还系统,所以每次都会发生缺页异常。

在内核空间,Linux 则通过 slab 分配器来管理小内存。可以把 slab 看成构建在伙伴系统上的一个缓存,主要作用就是分配并释放内核中的小对象。

对于用户空间,malloc 通过 brk() 分配;

malloc() 申请内存后,内存并不会立即分配,而是在首次访问时,才通过缺页异常陷入内核中分配内存。

3.2 内存回收

当内存紧张时,系统会通过一系列机制回收内存:

  • 回收缓存,如 LRU 算法;
  • 回收不常访问的内存,把不常使用的内存通过交换分区直接写到磁盘;
  • 杀死进程,通过 OOM(Out of Memory)直接杀死占用大量内存的进程。

4. 查看内存

4.1 查看系统内存 free

total:总内存大小;
used:已使用内存的大小,包含了共享内存;
free:未使用内存的大小;
shared:共享内存的大小;
buff/cache:缓存和缓存区的大小;
available:新进程可用内存的大小,包含未使用内存和可回收的缓存。


$ free
              total        used        free      shared  buff/cache   available
Mem:       16254236     6001652     3964020      349384     6288564     9565504
Swap:       2097148         768     2096380

4.2 查看进程内存 top

  • VIRT:进程虚拟内存大小,包括进程申请过的内存,即便没有分配;
  • RES:常驻内存大小,即实际使用的物理内存大小,不包括 Swap 和共享内存;
  • SHR:共享内存大小,如与其它进程共同使用的共享内存、加载的动态链接库和程序代码段等;
  • %MEM:进程使用的物理内存占系统内存的百分比。

4.3 Buffer 和Cache

两个角度 理解: Buffer 和Cache

角度一: man free
Buffer :是内核缓冲区用到的内存,对应的是 /proc/meminfo 中的 Buffers 值。

Cache: 是内核页缓存和 Slab 用到的内存,对应的是 /proc/meminfo 中的 CachedSReclaimable 之和。

角度二: man proc, 关于 meminfo 说明

  • Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。

  • Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。

Slab 包括两部分,SReclaimable 和 SUnreclaim 。

其中的可回收部分,用 SReclaimable 记录;
而不可回收部分,用 SUnreclaim 记录。

  1. 磁盘和文件写
# 清理文件页、目录项、Inodes 等各种缓存
$ echo 3 > /proc/sys/vm/drop_caches

读取随机设备,生成一个 50MB 大小的文件:

$ dd if=/dev/urandom of=/tmp/file bs=1M count=50

  1. 磁盘和文件的读: 结果同磁盘和文件写。

  2. vmstat 1 查看,cache 增长,buff 几乎不变。

$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0   1280 4392104 183452 5940636    0    0    68    22  313  118  6  7 87  0  0
 0  0   1280 4385552 183452 5940776    0    0     0   552 3795 8138  2  1 96  0  0
 0  0   1280 4385552 183452 5939872    0    0     0     0 3770 7785  1  1 97  0  0


5. 内存分析指标

在这里插入图片描述

  1. 内存分析工具

在这里插入图片描述

  1. 在这里插入图片描述

  2. 内存分析流程
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值