一些定义

  • Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。
  • 虚拟地址空间的内部又被分为内核空间和用户空间两部分
  • 并不是所有的虚拟内存都会分配物理内存,只有那些实际使用的 虚拟内存才分配物理内存,并且分配后的物理内存,是通过内存映射来管理的。
  • 内存映射,其实就是将虚拟内存地址映射到物理内存地址
  • 页表实际上存储在 CPU 的内存管理单元 MMU 中
  • TLB(Translation Lookaside Buffer, 转译后备缓冲器) 其实就是 MMU 中页表的高速缓存。
  • MMU 并不以字节为单位来管理内存,而是规定了一个内存映射的最小单位, 也就是页,通常是 4 KB 大小。
  • 而当进程访问的虚拟地址在页表中查不到时,系统会产生一个缺页异常,进入内核空间分配 物理内存、更新进程页表,最后再返回用户空间,恢复进程的运行。

内存回收

系统不会任由某个进程用完所有内存,在发现内存紧张时,系统就会通过一系列机制来回收内存。

回收缓存

使用 LRU 算法,回收最近使用最少的内存页

使用交换分区

回收不常访问的内存,使用 swap。其实就是将一块磁盘空间当做内存使用。

换出:将暂时不用的数据存储到磁盘中;换入:当进程访问这些内存时,再从磁盘中读取这些数据到内存中。

杀死进程

直接 OOM,杀掉占用大量内存的进程

杀的时候会根据 oom_score 来进行判断,内存越大分越大,cpu 占用越多分越小

命令

free -h

  1. [root@Linkin /]# free -h
  2. total used free shared buff/cache available
  3. Mem: 7.6G 326M 6.2G 480K 1.1G 7.0G
  4. Swap: 0B 0B 0B

top + M

  1. top - 20:29:20 up 10 min, 1 user, load average: 0.00, 0.09, 0.10
  2. Tasks: 92 total, 1 running, 91 sleeping, 0 stopped, 0 zombie
  3. %Cpu(s): 0.2 us, 0.2 sy, 0.0 ni, 99.5 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st
  4. KiB Mem : 7.6/8009024 [|||||||| ]
  5. KiB Swap: 0.0/0 [ ]
  6. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
  7. 1001 influxdb 20 0 566444 81360 16180 S 0.3 1.0 0:11.26 influxd
  8. 1025 root 20 0 799412 73760 27816 S 0.0 0.9 0:00.76 dockerd
  9. 1023 root 20 0 509024 40648 14164 S 0.0 0.5 0:00.37 containerd
  10. 1009 root 20 0 574204 17504 6128 S 0.0 0.2 0:00.32 tuned
  11. 746 polkitd 20 0 612344 12260 4772 S 0.0 0.2 0:00.03 polkitd

VIRT 是进程虚拟内存的大小,只要是进程申请过的内存,即便还没有真正分配物理内 存,也会计算在内。

RES 是常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括 Swap 和共享 内存。

SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及 程序的代码段等。

%MEM 是进程使用物理内存占系统总内存的百分比。