计算机的核心部分是 CPU,RAM 是 CPU 的前端门户,进入 CPU 的所有内容都将通过 RAM。例如,如果有一个正在加载的进程,则该进程将首先加载到 RAM 中,CPU 将从 RAM 获取进程数据。但为了使其更快,CPU 具有一级、二级、三级缓存。这些缓存就像 RAM一样,但是它集成在 CPU 上,并且CPU 上的缓存量非常小,因为它非常昂贵,而且对所有指令也不是很有用。

因此,进程信息是从 RAM 复制到 CPU,CPU 构建其缓存。缓存在 Linux 上的内存管理中也起着重要作用。

如果用户从硬盘请求信息,则将其复制到 RAM,并从 RAM 为用户提供服务。当信息从硬盘复制时,它被放置在所谓的页面缓存中。因此,页面缓存存储最近请求的数据,以便在再次需要相同的数据时使其更快。

如果用户开始修改数据,它也会进入RAM,从RAM到硬盘,但这只有在数据在RAM中停留足够长的时间时才会发生。数据不会立即从RAM写入硬盘,但为了优化对硬盘的写入,Linux采用了脏缓存的概念。它尝试缓冲尽可能多的数据,以创建有效的写入请求。因此,计算机上发生的一切都通过RAM。

所以,在 Linux 计算机上使用 RAM 对于 Linux 操作系统的良好运行至关重要。接下来讨论 Linux 内存管理的各个部分,并了解与此流程相关的不同术语。

二、了解虚拟内存

在分析 Linux 内存使用情况时,应该了解 Linux 如何使用虚拟内存和驻留内存。Linux 上的虚拟内存从字面上理解:它是可以引用 Linux 内核的不存在的内存量。

查看总物理内存:

代码语言:Bash

自动换行

AI代码解释


$ grep MemTotal /proc/meminfo MemTotal: 7023012 kB

查看虚拟内存:

代码语言:Bash

自动换行

AI代码解释


$ grep VmallocTotal /proc/meminfo VmallocTotal: 34359738367 kB

可以看到有32TB的虚拟内存。

如果在 Linux 中,当一个进程加载时,这个进程需要内存指针,而这些内存指针实际上不必引用实际的物理 RAM,这就是使用虚拟内存的原因。Linux 内核使用虚拟内存来允许程序进行内存预留。进行此保留后,其他应用程序无法保留相同的内存。进行预留是设置指针的问题,仅此而已。这并不意味着内存预留实际上也会被使用。当程序必须使用它保留的内存时,它将发出系统调用,即内存实际上将被分配。

三、什么是内存过度分配和 OOM?

top命令中,可以看到 virt 列和 res 列。

  • VIRT用于虚拟内存。这是进程当前分配的千字节数。

  • RES是Resident,这就是真正使用的内存。

展开

代码语言:Bash

自动换行

AI代码解释


top - 15:03:09 up 4:49, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 33 total, 1 running, 32 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.4 sy, 0.0 ni, 99.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st MiB Mem : 6858.4 total, 5317.5 free, 530.4 used, 1010.5 buff/cache MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 6082.8 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 19512 12496 8292 S 0.0 0.2 0:01.09 systemd 2 root 20 0 2280 1300 1188 S 0.0 0.0 0:00.00 init-systemd(Ub 7 root 20 0 2280 4 0 S 0.0 0.0 0:00.00 init 36 root 19 -1 47736 15292 14280 S 0.0 0.2 0:00.15 systemd-journal 56 root 20 0 21964 5916 4552 S 0.0 0.1 0:00.16 systemd-udevd 74 root 20 0 4492 172 20 S 0.0 0.0 0:00.00 snapfuse 75 root 20 0 4624 176 24 S 0.0 0.0 0:00.00 snapfuse 76 root 20 0 4848 1808 1340 S 0.0 0.0 0:00.76 snapfuse 77 root 20 0 4728 1744 1240 S 0.0 0.0 0:01.96 snapfuse 80 root 20 0 4972 1748 1240 S 0.0 0.0 0:01.19 snapfuse 87 systemd+ 20 0 25532 12636 8440 S 0.0 0.2 0:00.16 systemd-resolve 99 root 20 0 4304 2648 2404 S 0.0 0.0 0:00.02 cron 103 message+ 20 0 8584 4652 4120 S 0.0 0.1 0:00.28 dbus-daemon 130 root 20 0 30104 19232 10436 S 0.0 0.3 0:00.10 networkd-dispat 135 syslog 20 0 222400 5140 4312 S 0.0 0.1 0:00.02 rsyslogd 136 root 20 0 1984488 44964 18804 S 0.0 0.6 0:06.75 snapd 137 root 20 0 15324 7344 6400 S 0.0 0.1 0:00.19 systemd-logind 194 root 20 0 4780 3372 3132 S 0.0 0.0 0:00.08 subiquity-serve 201 root 20 0 3236 1064 980 S 0.0 0.0 0:00.00 agetty 213 root 20 0 3192 1088 1004 S 0.0 0.0 0:00.00 agetty 214 root 20 0 107216 21880 13256 S 0.0 0.3 0:00.05 unattended-upgr 310 root 20 0 721880 80592 21184 S 0.0 1.1 0:16.32 python3.10 343 root 20 0 2288 112 0 S 0.0 0.0 0:00.00 SessionLeader 344 root 20 0 2304 116 0 S 0.0 0.0 0:00.00 Relay(345) 345 fly 20 0 6216 5124 3376 S 0.0 0.1 0:00.04 bash 346 root 20 0 7524 4916 3992 S 0.0 0.1 0:00.00 login 403 fly 20 0 16928 9336 7860 S 0.0 0.1 0:00.04 systemd 404 fly 20 0 168756 3376 16 S 0.0 0.0 0:00.00 (sd-pam) 409 fly 20 0 6120 4900 3316 S 0.0 0.1 0:00.01 bash 421 root 20 0 44208 37496 10048 S 0.0 0.5 0:24.72 python3 609 root 20 0 293000 20340 17432 S 0.0 0.3 0:00.18 packagekitd 613 root 20 0 234492 6680 6048 S 0.0 0.1 0:00.06 polkitd 4847 fly 20 0 7788 3648 3044 R 0.0 0.1 0:00.00 top

可以看到,Linux系统为进程分配了大量的内存,如果将所有这些VIRT内存相加,会发现远远超过该系统中可用的物理 RAM 的总和。这就是所说的内存过度分配。

若要调整过度分配内存的行为,可以在/proc/sys/vm/overcommit_memory写入参数。此参数的值:

  • 默认值为 0,这意味着内核在授予内存之前会检查它是否仍有可用内存。

  • 1 表示系统认为在所有情况下都有足够的内存。这有利于执行内存密集型任务,但可能会导致进程自动终止。

  • 2 表示如果没有足够的可用内存,内核的内存请求将失败。

当任何应用程序或进程请求内存时,内核将始终接受该请求并“给予”。请注意,内核提供了一定数量的内存,但该内存未标记为“已使用”。相反,这被视为“虚拟内存”,只有当应用程序或进程尝试将某些数据写入内存时,内核才会将内存的该部分标记为“已使用”。

因此,如果突然一个或某个进程开始使用更多的驻留内存 (RES),内核需要满足该请求,结果是可能会遇到没有更多可用内存的情况。当系统内存不足时,这种情况被称为OOM(内存不足)情况,并且它正在耗尽内存。在这种情况下,kill命令将处于活动状态,它将杀死最不需要内存的进程,这是一种随机情况。因此,如果系统内存不足,内核将随机杀死一个进程。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐