Linux内存管理
1.内存–参考
物理内存:也就是安装在计算机中的内存条,比如安装了 2GB 大小的内存条,那么物理内存地址的范围就是 0 ~ 2GB。
虚拟内存:虚拟的内存地址。由于 CPU 只能使用物理内存地址,所以需要将虚拟内存地址转换为物理内存地址才能被 CPU 使用,这个转换过程由 MMU(Memory Management Unit,内存管理单元) 来完成。在 32 位的操作系统中,虚拟内存空间大小为 0 ~ 4GB。

页表 保存的是虚拟内存地址与物理内存地址的映射关系,MMU 从 页表 中找到虚拟内存地址所映射的物理内存地址,然后把物理内存地址提交给 CPU,这个过程与 Hash 算法相似。
内存映射是以内存页作为单位的,通常情况下,一个内存页的大小为 4KB(如图1所示),所以称为 分页机制
有些场景我们希望使用更大的内存页作为映射单位(如 2MB)。使用更大的内存页作为映射单位有如下好处:
- 减少
TLB(Translation Lookaside Buffer)的失效情况。 - 减少
页表的内存消耗。 - 减少 PageFault(缺页中断)的次数。
因为映射的内存页越大,所需要的 页表 就越小(很容易理解);页表 越小,TLB 失效的情况就越少。
使用大于 4KB 的内存页作为内存映射单位的机制叫 HugePages。
2.大页内存–参考
优点:
1) 大页内存TLB miss 很少,缺页中断也很少,对于内存的访问性能更好,对于占用大量内存的程序,性能提升比较明显,可以提升达到50%左右。
2) 大页内存的内存页不会swap到磁盘上。
缺点:
1) 必须使用特定的方式使用,比如采用mmap映射或者通过上面方式指定。
2) 程序使用内存小,却申请了大页内存,会造成内存浪费,因为内存分配最小单位是页。
1.查看是否支持
Linux系统采用hugetlbfs的特殊文件系统来加入对2MB和1GB的大页内存的支持,为了配置,先查看cpu是否支持:
1 | Copy cat /proc/cpuinfo |grep --color pse |
查看内核是否支持:
1 | Copy grep -i hugetlb /boot/config-4.18.0-193.el8.x86_64 |
cpu的功能列表中含有pse标识支持2MB的内存大页,含有pdpe1gb支持1GB的内存大页。
2.查看大页内存使用情况
1 | grep -i huge /proc/meminfo |
3.分配大页内存
如果分配2MB的大页内存比较简单,可以通过命令预留:
1 | Copyecho 1024> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages |
预留1024个2MB的大页即预留2GB的大页内存。
3.大页内存引起的杯具
如果只有4GB内存
1 | # cat /proc/meminfo|grep Huge |
占用
1 | 1033*2048/1024=2033MB |
解决办法
释放大页内存–参考(我暂时用的这个)
1 | echo 0 > /proc/sys/vm/nr_hugepages |
或者禁用大页缓存–参考
1 | vi /etc/sysctl.conf |
4.其它Linux命令
1.top命令–参考
top命令经常用来监控linux的系统状况,是常用的性能分析工具,能够实时显示系统中各个进程的资源占用情况。
1 | top [-d number] | top [-bnp] |
| 参数 | 含义 |
|---|---|
| -d number | number代表秒数,表示top命令显示的页面更新一次的间隔 (default=5s) |
| -b | 以批次的方式执行top |
| -n | 与-b配合使用,表示需要进行几次top命令的输出结果 |
| -p | 指定特定的pid进程号进行观察 |
top命令显示的页面还可以输入以下按键执行相应的功能(注意大小写区分的)
| 参数 | 含义 |
|---|---|
| ? | 显示在top当中可以输入的命令 |
| P | 以CPU的使用资源排序显示 |
| M | 以内存的使用资源排序显示 |
| N | 以pid排序显示 |
| T | 由进程使用的时间累计排序显示 |
| k | 给某一个pid一个信号,可以用来杀死进程(9) |
| r | 给某个pid重新定制一个nice值(即优先级) |
| q | 退出top(用ctrl+c也可以退出top) |
top前五条信息解释
top - 14:49:28 up 1:33, 1 user, load average: 0.00, 0.00, 0.00
| 内容 | 含义 |
|---|---|
| 14:49:28 | 表示当前时间 |
| up 1:33 | 系统远行时间,格式为时:分 |
| 1 user | 当前登陆用户数 |
| load average: 0.00, 0.00, 0.00 | 系统负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值 |
Tasks: 80 total, 2 running, 78 sleeping, 0 stopped, 0 zombie
| 内容 | 含义 |
|---|---|
| Tasks: 80 total | 进程总数 |
| 2 running | 正在运行的进程数 |
| 78 sleeping | 睡眠的进程数 |
| 0 stopped | 停止的进程数 |
| 0 zombie | 僵尸进程数 |
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
| 内容 | 含义 |
|---|---|
| 0.0%us | 用户空间占用CPU百分比 |
| 0.0%sy | 内核空间占用CPU百分比 |
| 0.0%ni | 用户进程空间内改变过优先级的进程占用CPU百分比 |
| 100.0%id | 空闲CPU百分比 |
| 0.0%wa | 等待输入输出的CPU时间百分比 |
| 0.0%hi | 硬中断(Hardware IRQ)占用CPU的百分比 |
| 0.0%si | 软中断(Software Interrupts)占用CPU的百分比 |
| 0.0 st | 用于有虚拟cpu的情况,用来指示被虚拟机偷掉的cpu时间 |
Mem: 1922488k total, 406936k used, 1515552k free, 11940k buffers
| 内容 | 含义 |
|---|---|
| 1922488k total | 物理内存总量 |
| 406936k used | 使用的物理内存总量 |
| 1515552k free | 空闲内存总量 |
| 11940k buffers | 用作内核缓存的内存量 |
Swap: 835576k total, 0k used, 835576k free, 111596k cached
| 内容 | 含义 |
|---|---|
| 835576k total | 交换区总量 |
| 0k used | 使用的交换区总量 |
| 835576k free | 空闲交换区总量 |
| 111596k cached | 缓冲的交换区总量 |
进程信息
| 列名 | 含义 |
|---|---|
| PID | 进程id |
| USER | 进程所有者的用户名 |
| PR | 优先级 |
| NI | nice值。负值表示高优先级,正值表示低优先级 |
| VIRT | 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
| RES | 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
| SHR | 共享内存大小,单位kb |
| S | 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 |
| %CPU | 上次更新到现在的CPU时间占用百分比 |
| %MEM | 进程使用的物理内存百分比 |
| TIME+ | 进程使用的CPU时间总计,单位1/100秒 |
| COMMAND | 命令名/命令行 |
2.free 命令
free 命令显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存。
默认按照k(b)的计数单位统计
1 | total:表示 总计物理内存的大小。 |
参数:
1 | -b 以Byte为单位显示内存使用情况。 |