该top
命令的输出显示一列Virt
- 虚拟内存消耗,但我不太明白虚拟内存是什么类型,为什么它的数量超过了实际消耗的 RAM 数量?Tobish,我有一个应用程序(微服务),它在运行时会消耗:
- 2.4G 内存
- 5.4G GPU显存(
cuda
) - 14.1G虚拟内存
同时在主机上:
- 6G内存
- 8G 显存
- 21G磁盘存储
- 没有交换
实际上:这个数字在 14.1G 中是什么意思?为什么它是最大数量的特工(特别是考虑到它swap
失踪了)?
该top
命令的输出显示一列Virt
- 虚拟内存消耗,但我不太明白虚拟内存是什么类型,为什么它的数量超过了实际消耗的 RAM 数量?Tobish,我有一个应用程序(微服务),它在运行时会消耗:
cuda
)同时在主机上:
实际上:这个数字在 14.1G 中是什么意思?为什么它是最大数量的特工(特别是考虑到它swap
失踪了)?
原则上什么是“虚拟内存”以及为什么需要它,在Wikipedia中有适当的描述,在 Tanenbaum 的“计算机体系结构”中描述得更好(在 Google 上很容易找到共享软件版本)。所以我允许自己跳过严格的定义,我将尝试“在手指上”解释它。
对于内存的每个请求,处理器使用特殊表¹(取决于系统并由操作系统管理)将虚拟地址( VA ) 转换为物理地址。每个进程都有自己的此类表,并且虚拟地址空间( AP ) 的大小通常比计算机上的实际内存大得多,因此并非所有 VA 在任何给定时间都在 RAM 中具有相应的地址。此外,可以将完全不同的实体连接到进程 AP:
mmap
)。因此,当处理器检测到对当前不在 RAM 中的地址进行了访问时,就会发生页面错误(page fault),然后控制权从进程转移到 OS 内核。然后操作系统内核确定请求的地址指的是什么:
SIGSEGV
。在相应的页面加载到 RAM 后,控制从分页处理程序返回,处理器将尝试执行它之前偶然发现的相同指令。
这实际上是设计使然,但您仍然可以注意到关键特性:
当进程请求内存时,在访问特定内存页之前不会分配物理内存。那些。过程可以做
这
VSZ
将增加一个千兆字节,但RSS
在填充之前不会改变:虚拟内存,除了“程序内存”,还包括各种内存映射文件。
VSZ
ps
'a 或 ' a 列Virt
htop
中的大值是可以的。¹ 为清楚起见,在 linux 中,与大多数架构上的大多数现代操作系统一样,使用了分页内存。此外,我们将只谈论她。
首先,分配大量虚拟内存是完全正常的行为,并且取决于应用程序的编写方式以及它如何使用这些内存。
Linux 中虚拟内存的分配由一个名为
vm.overcommit_memory
(您可以使用命令查看当前值sysctl vm.overcommit_memory
)的策略来调节,并且可以激活 3 个工作场景之一:0
- 内核启发式控制的虚拟内存分配策略,可以分配比 RAM+swap 更多的虚拟内存(但不是任意数量)。此策略通常默认设置。但它有一个缺点:当物理内存不足时,可以使用 OOM_KILLED 标志终止认为正在访问自己的合法地址空间的进程。1
- 内核不跟踪进程请求的地址空间量的策略,并允许分配与进程请求一样多的地址空间。它对于可以为自己分配数 TB 虚拟内存的各种 java 程序很有用。与 OOM_KILLED 相关的缺点也在这里。2
- 可以控制虚拟内存大小的策略。vm.overcommit_ratio
在这种情况下,通过根据公式调整核心来调节体积:那些。例如,在您的情况下,安装时
vm.overcommit_ratio = 50
,如果您不使用大页面,则分配的最大虚拟内存量可以是:6Gb * 50 / 100 + 0 = 3Gb
PS 可以看到当前huge_pages的数量
grep HugePages_Total /proc/meminfo