0x00 前言
在写完了 CPU 的的性能分析笔记后,接下来是分析内存的性能问题,在分析内存的性能问题之前,肯定是需要了解内存的原理,这里的原理指的是内存软件层面的原理,如内存如何进行分配、释放等等,而不是说内存的硬件结构、内存寄存器、TLB 等等。
0x01 内存映射
常常我们在买电脑前,我们都关心一个参数:内存大小,这直接关系到我们电脑的性能,但这里的大小指的是物理内存的大小,而在操作系统上,我们的程序在运行的过程中并不是直接使用物理内存的,而是用到了虚拟内存,即通过将物理内存映射成虚拟内存供进程使用,这也正是计算机世界的规则之抽象和分层。
当程序被执行的时候,所有用到的内存地址都是虚拟内存的地址,然后再由操作系统将虚拟地址转换成物理地址,这样程序便无需关心真正的物理地址是什么,从而在程序编译的时候无需知道真正的物理地址,同时不同的进程之间也起到的隔离的作用。
具体的内存映射可以总结出以下几点:
- 虚拟地址分为内核空间和用户空间,同时虚拟内存模型是一个倒着的栈,栈底是高地址。如下所示:
- 虚拟地址和物理地址之间是要通过一个东西关联的,就像一个索引,而这个东西就是页表,Linux 用的是四级页表
0x02 内存分配与回收
分配
C 标准库使用 malloc 函数提供内存分配,有两种实现方式:
- brk():分配小于 128k 的内存,通过移动堆顶的位置
- mmap():分配大于 128k 的内存,在文件映射段找一块空闲的内存分配出去
- slab 分配器: 分配小于 1k 的内存,用的内存是 blk 释放的被缓存起来的内存
优缺点
- brk(): 频繁内存分配会造成内存碎片
- mmap:内存用完了会放掉,然后再次申请会有缺页异常,使内核的负担增大
释放
- 回收缓存:LRU 算法
- 回收不常访问的内存,swap 到磁盘:可能会导致性能问题
- OOM:使用 oom_score 的权重杀进程
0x03 内存参数
free(全局)
- total: 总内存
- used: 已使用内存
- free: 未使用内存
- shared: 共享
- buff/cache: 缓存和缓冲
- available: 新进程
top (单个进程)
- VIRT(Virtual): 进程虚拟内存,只要申请过就会计算,即使没分配物理内存,所以会比实际的物理内存大很多
- RES(Resident): 常驻内存,即实际物理内存,不包括 swap
- SHR(Shared): 共享内存,比如根据前面的虚拟内存图所示,动态库段和程序代码段都属于共享内存,但也不是所有 Shared 都是共享的,有些非共享的动态库也算在了里面
- MEM%: 物理内存的占用百分比了
0x04 总结
今天的笔记总结下来就是,先不讨论内存的物理结构(或许后续会总结下计算机原理的内存硬件结构~),在软件层面使用内存:
- 不直接使用物理内存,进程是使用虚拟内存,这也是计算机抽象的一种体现
- 内存的分配和回收的方式的种类和方式
- 在 Linux 上如何查看内存的参数
在了解了内存的基本一些原理后,我们便可以进行深入的内存性能分析了。