内存使用情况查看
mem表示物理内存统计,swap表示硬盘上交换分区的使用情况,各列含义:
列 | 含义 |
---|---|
total | 表示内存总量 |
used | 表示所有已使用内存 |
free | 表示未使用内存 |
shared | 表示共享内存 |
buff/cache | 表示缓存区 |
available | 表示新进程可用量 |
内存分配和回收
当调用 malloc(动态内存分配)
申请内存时,系统调用 brk
嵌入到内核,会进行一次判断,是否有关于堆的 vma
。如果没有,就通过mmap
匿名映射一块内存给堆,并建立 vma 结构,挂到 mm_struct 描述符上的红黑树和链表上;然后回到用户态,通过内存分配器算法将分配的内存进行管理,返回给用户所需要的内存;
用户态申请大内存时,直接调用 mmap 分配内存,此时返给用户态的内存还是虚拟内存,直到第一次访问的内存返回,才进行真正的内存分配;其实通过 brk 返回的也是虚拟内存,但是经过内存分配器进行切割分配之后(切割就必须访问内存),全都分配到了物理内存
当进程在用户态通过调用 free 释放内存时,如果这块内存是通过 mmap 分配,则调用 munmap 直接返回给系统;否则内存是先返回给内存分配器,然后由内存分配器统一返还给系统,这就是为什么当我们调用 free 回收内存之后,再次访问这块内存时,可能不会报错的原因;
当然,当整个进程退出之后,这个进程占用的内存都会归还给系统
当内存耗尽后,oom(out of memory)
即 linux 系统在内存耗尽时自我拯救措施,它最大概率会选择那个内存占用率最高的进程,将其杀死,释放出内存
内存性能指标
1、进程内存情况
(1)虚拟内存
包括了进程代码段,数据段,共享内存,已经申请的堆内存和已经换出的内存等,注意,已经
申请的内存,即使还没有分配物理内存,也算作虚拟内存
(2)常驻内存
进程实际使用的物理内存,不包括swap和共享内存,一般会换算成占系统总内存的百分比,
也就是进程的内存使用率
(3)共享内存
包括与其他进程共同使用的真是的共享内存,还包括了加载的动态链接库以及程序代码段等
(4)SWAP内存
通过Swap换出到磁盘的内存
2、缺页异常
系统调用内存分配请求后,并不会立刻为其分配物理内存,而是在首次访问时,通过缺页异常来分配,缺页
异常包括两类
(1)可以直接从物理内存中分配时,称为次缺页异常
(2)需要磁盘I/O介入,比如Swap时,被成为主缺页异常,主缺页异常升高,意味着需要磁盘I/O,会导致
内存访问变慢很多(swap是交换分区安装系统时已存在)
3、swap的使用情况
swap的换入换出速度,已用及剩余空间。
(1)换入换出速度、表示每秒换入换出内存的大小
(2)已用及剩余空间、表示已使用和没有使用的内存空间
内存性能分析工具
如何快速分析内存的性能指标
1、free、top,查看整体内存使用情况
2、vmstat、pidstat,截取一段时间的趋势,从而判断出内存的问题类型
3、详细分析。如内存分配分析,具体进程分析,缓存/缓冲区的内存使用分析等
内存优化思路
1、尽量使用缓存缓冲区来访问数据,比如可以使用堆栈明确声明内存空间,来存储需要缓存的数据,也可以用 redis 这类外部缓存组建,优化数据的访问
2、减少内存的动态分配,例如可以使用内存池,大页(HugePage)等
3、禁止Swap,如果必须开启swap,那就降低swappiness的值,减少回收swap的使用倾向
4、通过 /proc/[PID]/oom_adj ,调整核心应用的 oom_score,可以保证内存耗尽时,核心应用也不会被 oom 杀死