如何驯服Linux的响应能力,内存和页面调度


27

溢出的第一个问题=)... + 100赏金。直到现在我都没有想到我真正关心的东西:

我真的受够了Linux桌面响应能力的状态,例如http://brainstorm.ubuntu.com/item/85/-在低可用RAM或磁盘吞吐量高的情况下,系统速度减慢到一个爬行 ; 对于需要良好性能的应用程序来说,这绝对是可怕的。此外,UI完全没有响应。例如,将其与OS X进行比较,在OS X中,如果应用程序正在占用资源,则可以始终单击选项以强制退出它,而在Linux中,我什至无法alt-tab或切换桌面,甚至无法ctrl-alt-f1来获取资源。终端-可以,每次操作大约需要1-2分钟。

我使用gkrellm以便可以看到情况的发展。通常,内存利用率会很高,或者磁盘吞吐量会急剧上升。

这不是坏硬件,具有2.6GHz四核和4GB的800MHz DDR2 RAM(本来有6GB,但是由于硬件不兼容而无法与旧版本混合使用)。当我不可避免地获得更多的RAM时,这个问题可能会消失,但是我不认为这是问题的核心。我什至在不同的磁盘上有两个交换分区。

我觉得问题有三重:

  • 占用大量内存的失控程序-必须为这些程序制定法律,并限制其程序
    • (例如,Chrome上的标签页,每个标签页为20-50MB,其中一些标签页可以使用数百MB)
    • (例如其他程序,例如update-db和indexers,我不得不禁用它们并从cron中删除,因为它们每次运行都会使系统减慢抓取速度,等等)
  • 在内核或总线争用中发生了某种可怕的事情,例如高磁盘吞吐量情况使整个系统缓慢爬行(也许是通过调出重要程序)
  • 内核没有根据资源(例如内存,分页甚至处理器利用率)来对UI或重要程序进行优先级排序

投票转到:

因此,我正在寻找所有此类程序都无法使用的解决方案。特别是,我正在寻找一种解决方案,以使进程按比例降低速度,而系统和其他程序仍然完全不受影响且响应时间足够长,可以手动杀死某些内容。而且,窗口管理器进程(以及可能影响UI响应性的其他任何事物)在所有情况下都应响应。

特别地,我对/etc/security/limits.confman limits.conf)感兴趣,但是担心这只会给每个用户提供控制权,并且文件中的注释示例在描述或从何处开始时似乎都不太透明。我希望它能limits.conf奏效,但是即使它不起作用,或者它不是解决我的问题的合适方法,或者像我想要实现的那样精细,也不会感到惊讶。每个进程的名称limits.conf将是理想的,再次假设limits.conf有效。我很乐意尝试人们提供的limits.conf,以测试它是否有效,尽管我现在对所有解决方案都开放。

深入了解OS X如何保持如此出色的UI响应能力也可能很有用。

我已经调整了我/tmp和cache文件夹的位置tmpfs,并且通常磁盘利用率接近零。

模糊相关的主题:

  • 内存过量使用

我认为无效的答案:

  • swapoff (这仍然使记忆猪程序摆脱谋杀,并且如果记忆真的不好,系统将永久冻结-可以向任何建议进行调整的人提供支持,这些调整可以在交换之前针对OOM杀手,并针对特定程序)
  • echo ?? > /sys/.../swappiness (没有明显的影响)
  • nice (从未工作过)
  • ionice (从未发现任何差异)
  • selinux(程序不兼容似乎是一场噩梦)
  • 实时linux,即可以中断内核(不想处理编译和更新自定义内核;如果已迁移到存储库中则可以)
  • *

嗯,我似乎无法悬赏;我想链接不会在48小时内显示出来吗?...好吧,我将发布具有所有获得的声誉的赏金
user76871 2011年

1
+1,这是我每天在Linux桌面上遇到的最大的问题。我偶尔冻结一次,也许每两周一次,但是这些冻结次数通常不足以引起特别的烦人。但是,就像您所说的,IO利用率很高的应用程序似乎只是一个问题:CPU利用率很高的应用程序对总体系统性能几乎没有影响。不知道ionice,如果它能够正常工作,似乎将是解决此问题的正确方法。
crazy2be

1
3年后,这在Linux上仍然是一个问题。@ crazy2be或user76871,我不认为您在此期间找到了解决方案?
谷氨酰胺

@Glutanimate:是的,32GB的物理RAM以及不少(嗯,也许是16GB ...但这正在推动它),也可以保证大量的视频RAM。这不能解决由于CPU过多或中断或其他原因导致的无响应,但可以防止低内存情况下的无响应。
user76871 2014年

Answers:


6

听起来您的系统即将进行大量交换。使用vmstat 1可能会揭示一些细节-只需让它在终端窗口中运行并在减速开始时切换到该窗口即可。

与其将/ tmp和“ cache”放入tmpfs中,我不使用带有该noatime选项的普通磁盘文件系统。无论如何,经常将使用过的数据保留在缓存中,并且可以将较旧的数据写入磁盘以为应用程序腾出一些RAM。如果/ tmp和/或缓存变大,这可能会有所帮助。


1
+1提及noatime
LawrenceC

谢谢您的提及noatime,很遗憾,我曾经使用该安装选项,但我认为它对确保响应速度没有多大帮助(尽管它可以帮助您确保磁盘不过度工作)。只是要确保我在当前设置中重新启用了noatime。但是,具有noatime的非tmpfs似乎有些奇怪,因为我仍然认为必须进行大量写入。
user76871 2011年

+1,已尝试vmstat 1-在
断断续续

2
哎哟。从未见过需要如此繁重交换工作的linux系统。您是否检查df -m过tmpfs文件系统中有多少内存?某些东西正在相对快速地消耗您的RAM。
Turbo J

感谢您的建议,并教给我有关该-m选项的信息。不幸的是,这df -h -m似乎表明我仅有100MB的内存在使用中tmpfs,因此我怀疑它是否与将内存用于tmpfs和缓存有关。这似乎并不罕见。当它们的RAM被推到接近极限时,我已经在多个发行版上发生过这种情况。
user76871 2011年

5

我不是内核开发人员,但是我花了多年时间思考这个问题,因为我多次遇到这个问题。实际上,我为整个情况想出了一个隐喻,所以让我告诉你。我会在我的故事中假设“交换”之类的东西不存在。无论如何,现在换32 GB RAM并没有多大意义。

想象您附近的某个地方,那里的水通过管道与每座建筑物相连,而城镇需要管理用水量。假设您每秒仅生产100单位水(由于没有储水箱,所有未使用的容量都会浪费掉)。每个家庭(家庭=一个小应用程序,一个终端,时钟小部件等)每秒需要一个1单位的水。一切都很好,因为您的人口大约为90,所以每个人都得到足够的水。

现在,市长(=您)决定要开一家大餐厅(=浏览器)。这家餐厅将容纳多位厨师(=浏览器标签)。每个厨师每秒需要1单位水。您从10位厨师开始,因此整个社区的总耗水量为100单位水,这仍然很好。

现在,有趣的事情开始了:您在餐厅雇用了另一位厨师,这显然使总需水量达到了101。你需要做点什么。

水管理(=内核)有3个选项。

1.第一个选项是刚刚拔下谁最近没有使用的水家的服务。很好,但是如果断开连接的房屋要再次使用水,则他们将需要再次进行冗长的注册过程。管理层可以断开多个房屋的连接,以释放更多的水资源。实际上,他们将断开最近未用水的所有房屋的连接,从而始终保持一定量的免费用水。

尽管您的城镇保持运转,但不利之处在于进度会停滞不前。您的大部分时间都花在等待水管理上以恢复服务。

这就是内核对文件支持页面的处理。如果运行大型可执行文件(例如chrome),则会将其文件复制到内存中。当内存不足或最近没有访问过某些部分时,内核会丢弃这些部分,因为它仍然可以从磁盘重新加载它们。如果做得过多,这会使您的桌面停顿下来,因为一切都将在等待磁盘IO。请注意,当您开始执行大量IO时,内核还将丢弃许多最近最少使用的页面。这就是为什么在您复制了多个大文件(如DVD图像)之后切换到后台应用程序需要花费一些时间的原因。

这对我来说是最烦人的行为,因为我讨厌筹码,而您对此没有任何控制权。能够将其关闭会很好。我在想一些类似的东西

sed -i 's/may_unmap = 1/may_unmap = (vm_swappiness >= 0)/' mm/vmscan.c

然后可以将vm_swappiness设置为-1以禁用此功能。在我的小测试中,这很好用,但是我不是内核开发人员,所以我没有将它发送给任何人(显然,上面的小修改还不完整)。

2。管理层可以拒绝新厨师的饮水要求。最初听起来是个好主意。但是,有两个缺点。首先,有些公司即使不使用也要求大量的用水。这样做的一个可能原因是避免他们需要额外水时与水管理部门交谈的所有开销。他们的用水量根据一天中的时间上下波动。以餐厅为例,与午夜相比,公司在中午需要更多的水。因此,他们要求使用所有可能使用的水,但这浪费了午夜的水分配。问题在于,并非所有公司都能正确预见其高峰使用量,因此他们提出了更多的要求,希望他们永远不必担心提出更多要求。

这就是Java的虚拟机的作用:它在启动时分配一堆内存,然后从那里开始工作。默认情况下,内核只会在Java应用程序实际开始使用内存时才分配内存。但是,如果禁用过量使用,内核将认真对待保留。仅当分配实际具有分配资源时,它才会允许分配成功。

但是,这种方法还有另一个更严重的问题。假设有一家公司每天开始请求一个单位的水量(而不是10个步骤)。最终,您将达到一个免费单位为0的状态。现在,该公司将无法分配更多资源。没关系,不管怎么说,谁在乎大公司。但是问题是小家庭也将无法请求更多的水!您将无法建造小型公共浴室来应对游客的突然涌入。您将无法为附近森林中的火灾提供紧急用水。

用计算机术语来说:在内存不足的情况下,如果没有过量使用,您将无法打开新的xterm,您将无法ssh进入计算机,也将无法打开新的选项卡以搜索可能的内容修复。换句话说,禁用过量使用也会使您的桌面在内存不足时变得无用。

3.现在,这是当公司开始使用过多水时解决问题的有趣方法。水管理炸毁了它!从字面上看:它去了餐厅的现场,将炸药扔进去,然后等它爆炸。这将立即大量减少城镇的用水需求,因此新人们可以搬进来,可以创建公共浴室等。作为市长,您可以重建餐厅,希望这次所需的用水量减少。例如,如果内部人员过多,您将告诉人们不要进入餐厅(例如,您将打开较少的浏览器标签)。

实际上,这是内核在所有选项都用完并且需要内存时执行的操作:它称为OOM杀手。它选择一个大型应用程序(基于许多启发式方法)并将其杀死,从而释放了大量内存,但维护了响应式桌面。实际上,Android内核会更加积极地执行此操作:当内存不足时,它会杀死最近最少使用的应用程序(相比之下,股票内核仅在万不得已时才这样做)。这在Android中称为Viking Killer。

我认为这是解决该问题的最简单的方法之一:好像您没有比这更多的选择,所以为什么不早于迟早解决它,对吗?问题在于内核有时会做很多工作来避免调用OOM杀手。这就是为什么您看到您的桌面非常慢并且内核对此无能为力的原因。但是幸运的是,您可以自己调用OOM杀手!首先,确保启用了魔幻的sysrq键(例如echo 1 | sudo tee /proc/sys/kernel/sysrq),然后每当您感到内核的内存不足时,只需按Alt + SysRQ,Alt + f。

好的,这一切都很好,但您想尝试一下吗?低内存情况很容易重现。我有一个非常简单的应用程序。您将需要运行两次。第一次运行将确定您有多少可用RAM,第二次运行将导致内存不足。请注意,此方法假定您已禁用交换功能(例如,执行sudo swapoff -a)。代码和用法如下:

// gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int limit = 123456789;
    if (argc >= 2) {
        limit = atoi(argv[1]);
    }
    setbuf(stdout, NULL);
    for (int i = 1; i <= limit; i++) {
        memset(malloc(1 << 20), 1, 1 << 20);
        printf("\rAllocated %5d MiB.", i);
    }
    sleep(10000);
    return 0;
}

这是您的用法:

$ gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
$ ./eatmem
Allocated 31118 MiB.Killed
$ ./eatmem 31110
Allocated 31110 MiB.Killed

第一次调用检测到我们有31,118 MiB的可用RAM。因此,我告诉应用程序分配31,110个MiB RAM,以便内核不会杀死它,但会耗尽我几乎所有的内存。我的系统冻结了:即使鼠标指针也没有移动。我按了Alt + SysRQ,Alt + f,它杀死了我的eatmem进程,系统得到了恢复。

即使我们涵盖了在内存不足的情况下的处理方法,但最好的方法(就像其他任何危险的情况一样)是首先避免使用它。有很多方法可以做到这一点。我见过的一种常见方法是将行为异常的应用程序(如浏览器)放入与系统其余部分不同的容器中。在这种情况下,浏览器将无法影响您的桌面。但是预防本身不在问题的范围之内,所以我不会写它。

TL; DR:尽管当前尚无法完全避免分页,但可以通过禁用过量提交来缓解整个系统暂停。但是在内存不足的情况下,您的系统仍将无法使用,但方式会有所不同。无论上面如何,在内存不足的情况下,请按Alt + SysRQ,Alt + f可以终止内核选择的大部分过程。几秒钟后,系统应恢复其响应能力。这假定您已启用了不可思议的sysrq密钥(默认情况下未启用)。


我以这种资源的赏赐而获得了我所有的声誉,因此我什至无法发表评论:)最后,我得到了一些感谢,谢谢您!我一直在使用8GB笔记本电脑时一直在处理此问题(这很疯狂,但是那几天我的系统经常出现内存不足的情况)。最近,我找到了这个项目:github.com/rfjakob/earlyoom,它可以通过在太晚之前杀死一些进程来防止系统挂起。
弗拉德·佛罗洛夫

4

将所有临时文件和缓存文件放在a上tmpfs会减少您的可用RAM数量,因此您可能会导致系统早于没有此情况就需要进行交换。

听起来您的某些应用程序依赖某种形式的内核工具或驱动程序而变得超载。除了使用浏览器和索引器之外,您无需过多介绍其他类型的应用程序,并且已禁用索引器。

您可以尝试切换到消耗较少资源的桌面环境或窗口管理器,例如LXDE或IceWM。在工作中,我使用安装了LXDE和ROX-Filer的Linux系统,以实现非常小的桌面环境。此Linux系统的目的是运行VMWare Player,以便我可以同时运行Windows XP和Windows 7。这与您所说的硬件规格相似,在我要承受的重负荷下,我没有太多响应性问题。我对Linux本身没有任何响应性问题(通常是VM有时使我稍等片刻,并期望在2个VM + 1个OS之间共享1个磁盘),并且始终能够在任何时候挂起或关闭VM我想要。

因此,对我来说,这表明您正在运行的特定应用程序存在一些问题。

磁盘驱动器是否启用了DMA?(使用hdparm)如果使用全盘加密,则要求所有磁盘流量都通过CPU,这抵消了DMA的许多好处。这样做的结果是高磁盘流量会导致CPU峰值,然后会使整个系统变慢。(编辑:为了澄清,禁用或使用DMA dm-crypt将在高磁盘流量期间导致较高的CPU使用率)


2
问题的重点不是WM膨胀并且导致系统变慢(在正常使用情况下它可能完全响应),而是当内核内存不足并必须进入时,内核没有适当地对应用程序进行优先级排序大量交换。我在曾经使用过的每个台式机Linux上都遇到过这个问题,尽管使用更轻量的程序或添加更多的ram可能有所帮助,但这并不能解决问题的根源。
crazy2be 2011年

在我以前的文章中,我说过:“听起来您的某些应用程序依赖某种形式的内核工具或驱动程序而变得超载。” 因此,瓶颈可能在特定的内核模块中。我不是内核专家,但是我确定内核方面(尤其是模块方面)的内存分配与用户层方面的内存分配有所不同。内核方面的CPU利用率也可能有不同的处理方式(不知道是否可以“很好地”使内核进程运行)。在不了解所涉及的特定应用程序的情况下,我无法发表更多评论。
LawrenceC

另外,如果您使用的FUSE NTFS可能会导致运行缓慢。
LawrenceC

1
我知道,基于tmpfs的基于RAM的文件系统(显然)会导致RAM更快用完,而轻量级的WM可以稍微减轻根本问题的症状。由于向磁盘写入的响应速度较慢,我感到使用tmpfs的压力很大。但是,仍然感谢您的建议,尤其是有关DMA的部分,我已将其添加到可能相关主题的列表中。出于记录,我相信DMA已启用,并且我没有使用加密文件系统。
user76871 2011年

1

这是Linux调度程序的常见问题。每当发生IO繁重的活动时,系统就会减速到爬网的速度。除非您热衷于内核黑客,否则您实际上没有很多事情可以改善这种情况:)

也许这些可以帮助:

http://www.phoronix.com/scan.php?page=article&item=linux_2637_video&num=1

http://www.osnews.com/story/24223/Alternative_to_the_200_Lines_Kernel_Patch_that_Does_Wonders_


1
我记得,这些内核补丁实际上仅在您正在编译程序或在终端中尝试与GUI应用程序进行交互时执行CPU(和IO?)占用大量内存的其他操作时才有意义。不幸的是,在一个GUI应用程序正在做繁重的工作,而您试图与另一个GUI应用程序一起工作的更常见的情况下,它没有帮助。
crazy2be

0

即使问题已经存在了两年多,并且@ypsu的回答很好,但是由于缺少RAM而使基于Linux的系统变坏的情况仍然存在。

这是我对问题的观察:即使我根本没有进行交换,一旦系统内存不足,硬盘驱动器指示灯也会亮起,因为它是100%的磁盘负载。考虑到这一事实,似乎根本原因是内核试图通过卸载可以从磁盘还原的内容(即,当然是共享库)来释放内存。由于GUI应用程序通常具有大量的共享库,因此系统似乎认为仅卸载其中的一部分就足够了,但这仅在下一次用户空间操作(要求将这些卸载的库返回)之前起作用。这似乎是最有可能导致无休止循环的卸载共享库并将其加载回的情况。

有一个项目充当用户空间守护程序,在为时已晚之前,它会杀死最消耗内存的进程:https : //github.com/rfjakob/earlyoom

另外,我过去经常使用对内存要求很高的应用程序(例如Chrome)具有有限内存限制的Docker容器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.