我的经验是,在物理内存耗尽之前,Linux 可以正常工作。一旦使用交换空间,性能就会严重下降并且 GUI 变得无响应。
这个问题不限于特定的发行版或桌面,因为我已经尝试了一些(问题仍然存在)。
我该怎么办?
是否可以让系统抢先换出非活动页面 ( vm.swappiness),但在系统耗尽 RAM(而不是耗尽内存)并被迫交换时调用 oom-killer?
最终目标是防止系统在由于主要页面错误而开始抖动磁盘时停止运行,但仍然让不活动的页面被换出。
另一个愿望是配置系统在 oom-killer 触发之前强制使用多少交换内存。这样系统就可以稍微进行交换,只要它不会走得太远。或者我可以在使用所有 RAM 之前设置这样一个阈值来触发 oom-killer,这样文件系统缓存总是有空间(从而避免更多的磁盘抖动)。
这似乎并不难做到。似乎您可以告诉 oom-killer 在系统使用/空闲 X ram 时触发。但这就是我问的原因;我不知道。
为了澄清起见,我不打算关闭交换或调整vm.swappiness参数
在他的自传Just for Fun 中,Linus 提到了“页面到磁盘”功能,该功能对于使 Linux 成为当时 Minix 和其他 UNIX 克隆的有价值的竞争对手至关重要:
我记得,在 12 月,德国有一个人只有 2 兆字节的 RAM,他试图编译内核,但无法运行 GCC,因为当时 GCC 需要超过 1 兆字节的内存。他问我是否可以使用不需要那么多内存的较小编译器来编译 Linux。所以我决定即使我不需要特定的功能,我也会为他实现。它被称为页到磁盘,这意味着即使某人只有 2 毫克 RAM,他也可以使它看起来更多地使用磁盘作为内存。那是 1991 年圣诞节前后。
页面到磁盘是一件相当大的事情,因为这是 Minix 从未做过的事情。它包含在 0.12 版本中,该版本于 1992 年 1 月的第一周发布。立即,人们开始将 Linux 不仅与 Minix 进行比较,而且与 Coherent 进行比较,后者是由 Mark Williams 公司开发的小型 Unix 克隆。从一开始,添加页面到磁盘的行为就使 Linux 在竞争中脱颖而出。
那是Linux起飞的时候。突然间有人从 Minix 切换到 Linux。
他基本上是在谈论swapping这里吗?对 Linux 有一些历史观点的人可能会知道。
什么设置的大小tmpfs?(在我的机器上,它驻留在 中/dev/shm)我可以看到它在 中的条目/etc/fstab,但看不到它的大小。检查时df -h,它似乎是系统中安装的物理内存大小的一半。这是默认行为吗?
另外,如果满了会怎样?它是否会动态扩展以迫使其他正在运行的程序进入swap?tmpfs本身是否进入swap分区?
最后,什么优先考虑内存tmpfs或应用程序?即,如果我有tmpfs足够的内存(例如 40% 的物理内存)并且我的程序需要 70% 的物理内存,那么哪一个获得优先级?
当我的 Linux 系统接近分页时(即,在我的情况下,16GB ram 几乎已满,16GB 交换完全空),如果新进程 X 尝试分配一些内存,系统将完全锁定。也就是说,直到不成比例的页面数量(与 X 的内存分配请求的总大小和速率)被换出。请注意,不仅 gui 变得完全没有响应,而且甚至像 sshd 这样的基本服务也完全被阻止。
这是我用来以更“科学”的方式触发这种行为的两段代码(诚然粗糙)。第一个从命令行获取两个数字 x,y 并继续分配和初始化多个 y 字节块,直到分配的总字节数超过 x 为止。然后无限期地睡觉。这将用于使系统处于寻呼的边缘。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
long int max = -1;
int mb = 0;
long int size = 0;
long int total = 0;
char* buffer;
if(argc > 1)
{
max = atol(argv[1]);
size = atol(argv[2]);
}
printf("Max: %lu bytes\n", max);
while((buffer=malloc(size)) != NULL && total < max) {
memset(buffer, …Run Code Online (Sandbox Code Playgroud) 在有关交换文件的讨论中(“我应该创建一个吗?”),我经常看到一个晦涩的提及“在某些情况下交换文件弊大于利”。这通常与“如果你有 X GB 或更多 RAM,则不需要交换”一起出现,通常有可靠的论据支持。然后显然存在诸如此处表达的反驳论点。
我可以想象一个后台运行的应用程序或服务foo,其正确功能取决于即时内存访问。删除用于交换的内存空间foo会减慢对其的访问速度,从而foo导致警告、错误甚至完全失败。
然而这就是我所得到的,实际的事实仍然难以捉摸。例如,我的 Linux 机器有 64GB RAM,允许我同时运行多个虚拟机。此时,许多 Linux 用户决定根本不进行交换,但我保留了 16GB 以防万一 - 驱动器空间很便宜,但经典swap = 2x RAM似乎有点夸张。
澄清一下:RAM/交换区比率或是否应该首先分配交换区超出了问题的范围。
我正在尝试诊断无头服务器上的一些随机段错误,一件看起来很奇怪的事情是它们似乎只在内存压力下发生,而且我的交换大小不会超过 0。
如何强制我的机器进行交换以确保它正常工作?
orca ~ # free
total used free shared buffers cached
Mem: 1551140 1472392 78748 0 333920 1046368
-/+ buffers/cache: 92104 1459036
Swap: 1060280 0 1060280
orca ~ # swapon -s
Filename Type Size Used Priority
/dev/sdb2 partition 1060280 0 -1
Run Code Online (Sandbox Code Playgroud) 如果我的桌面内存不足并且交换了很多,那么我会释放或杀死浪费我 RAM 的应用程序。但是,在那之后,我所有的桌面/应用程序都被交换了并且速度非常慢,你知道一种“取消交换”(从交换空间重新加载到内存中)我的桌面/应用程序的方法吗?
我在网上看到一些帖子,显然有人抱怨托管 VPS 意外杀死进程,因为他们使用了过多的 RAM。
这怎么可能?我认为所有现代操作系统都通过对物理 RAM 上的任何内容使用磁盘交换来提供“无限 RAM”。这样对吗?
如果一个进程“由于内存不足而被杀死”,可能会发生什么?
我正在设置突袭。sda在安装过程中使用,我刚才复制的分区表sda来sdb像这样:
$ sudo sfdisk -dL /dev/sda > partition_table_sda
$ sudo sfdisk /dev/sdb < partition_table_sda
Run Code Online (Sandbox Code Playgroud)
但是我注意到sda交换空间有一个 uuid,但sdb没有:
$ sudo blkid
/dev/sda5: UUID="vvvvvvvv-wwww-xxxx-yyyy-zzzzzzzzzzzz" TYPE="swap"
/dev/sda1: UUID="vvvvvvvv-wwww-xxxx-yyyy-zzzzzzzzzzzz" TYPE="ext4"
/dev/sdb1: UUID="vvvvvvvv-wwww-xxxx-yyyy-zzzzzzzzzzzz" TYPE="ext4"
Run Code Online (Sandbox Code Playgroud)
分区看起来是正确的,只是缺少 uuid:
$ sudo fdisk -l
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): …Run Code Online (Sandbox Code Playgroud)