当我的进程占用大量内存或运行许多 CPU 密集型进程时,通常甚至很难登录系统。我想防止这种情况并始终保持系统响应。有什么方法可以实现这一点吗?
澄清编辑:
我正在谈论我遇到相同症状的两种不同情况:
内存负载非常高。单个进程消耗接近或超过 64GB 的可用 RAM。当系统使用率接近 100% 时,程序会变得无响应。
CPU 负载非常高,调度问题。10k 个可运行进程会导致同样的问题。请注意,这不是 100% CPU 负载的问题。当我 kill -STOP 除 200 个进程之外的所有进程时,所有 32 个 CPU 都保持 100% 负载,但系统可用性更高。
关于我所认为的“系统”的问题。我理解 shell 进程和我的其他用户进程之间没有概念上的区别,但这只是使它们不同的问题。有一些选项,如 niceness,可以做到这一点。但如上所述,niceness 至少在案例 (2.) 中没有解决问题。
我完全控制了这些系统,并且在所有情况下都能够使用 kill -STOP 或仅 Cc 来停止作业。我想要修复的是,这变得非常困难,并且当使用 GUI 时有时是不可能的,因为输入处理速度非常慢,甚至根本无法处理。 我希望总体上解决这个问题,而不是对某些特定的工作做出改变。
我尝试过的事情:
对于我现在正在运行的许多进程,我刚刚将所有正在运行的进程重新设置为 +5,但这似乎没有帮助。也没有将它们设置为 19。
正如其中一个答案所建议的那样。我尝试使用
sudo schedtool -D $(pgrep -u myuser progname -d " ")
和将调度程序策略更改为IDLEsudo sh -c 'for pid in $(pgrep -u myuser progname); do chrt -i -p 0 $pid; done;'
这似乎在一定程度上改善了情况。
答案1
问题在于您的内存已经饱和,因此操作系统必须释放磁盘缓存并交换程序及其数据。
交换是一种在达到物理内存限制时保持系统正常运行的方法。在负载较轻的系统中,这意味着系统可以继续运行,当内存紧张时,系统会将内存调出,然后在需要时重新调入,而影响很小。
大多数操作系统会根据“最近最少使用”的原则刷新程序并替换代码。很难对内存的“优先级”做出任何假设,因为内存负载会发生变化,而“优先级”是主观判断更重要的滑坡。对一个系统来说更重要的东西对另一个系统来说可能不那么重要。命令行程序只是其他程序,不可能将它们与用户运行的其他程序区分开来。
由于您的系统负载很重,许多进程占用大量内存,因此您遇到了争用问题。当操作系统试图将某些内容移出到磁盘以释放一些内存时,另一个进程已经请求了一些需要重新加载的其他页面。每个重新加载某些内容的请求都会将其他内容移出。
在 10,000 个进程中,任何系统如何确定哪个进程应优先于看起来像任何其他程序请求的“系统”命令行程序请求?
另一个问题是硬盘寻道时间。对于旧式 HDD,移动驱动器磁头并开始读取或写入的时间约为 9.5 毫秒。由于不同区域同时发生大量请求,寻道时间可能超过其他所有时间,并将实际可用时间和带宽减少到令人惊讶的小数字。SSD 可以提供帮助,但如果您的内存有限,那么它只能提供有限的帮助。
类似的瓶颈可能发生在整个系统中,并表现出不同的症状。操作系统可以管理大量同时运行的程序,但它本身仍然“只是”一个程序,需要时间来完成其他所有工作。交换文件的使用只是最极端的瓶颈之一。
以这种方式淹没一个系统并期望它“处理它”并不是一个好主意。
如果您使用的内存一直超过现有内存,那么答案就是购买更多内存。如果您有数千个进程争用硬盘时间来读取或写入数据,那么您需要将负载分散到更多机器或驱动器上。
对于您的其他情况,拥有 10,000 个活动进程时,您的问题既是争论问题,也是不切实际的期望问题。
一个问题是,“好感”并不一定总是优先级较低。这取决于操作系统调度程序,添加越来越多的进程实际上可能会不利于建立公平和有用的系统,因为您最终会减少分配给任何给定进程的时间量。
请参阅我们 Unix 姊妹网站上的这个问题工作怎样才好?描述了完全公平调度程序:
CFS 在调度期间有一个目标延迟。较小的目标延迟可带来更好的交互性,但随着目标延迟的降低,切换开销会增加,从而降低整体吞吐量。
...
现在考虑两个进程,一个进程的 niceness 为 0(默认值),另一个进程的 niceness 为 5。相应权重之间的比例差大约为 1/3,这意味着优先级较高的进程接收大约 15 毫秒的时间片,而优先级较低的进程接收 5 毫秒的时间片。
在这个调度程序下,好处意味着你的 10,000 个进程应该获得的时间更少,但由于数量庞大,您可能会达到“公平”调度的时间片值的下限,这意味着没有人获得足够大的时间片。您甚至可能达到将任务拉入或拉出 CPU 的时间占主导地位的极限。
这实际上与硬盘争用相同。您迫使系统花费更多时间在进程之间切换,而不是花费任何有用的时间处理任何给定的进程。
您可以在以下位置找到有关调度程序的更多信息http://man7.org/linux/man-pages/man7/sched.7.html
使用更合理数量的进程(100 到 200)会导致在操作系统任务和进程之间分配合理的时间。
您不应该同时开始 10,000 项任务,而应该在旧任务完成后再开始新任务。