我认为这个问题有点类似于这线。
无论我是否启用或禁用交换,只要实际使用的 RAM 量开始接近最大值并且几乎没有剩余空间用于磁盘缓存,系统就会变得完全没有响应。
磁盘疯狂旋转,有时经过 10-30 分钟的漫长等待后才会解冻,有时则不会(或者我失去了耐心)。有时如果我行动迅速,我可以设法慢慢打开控制台并关闭一些占用内存的应用程序(如浏览器),系统几乎立即解冻。
由于这个问题,我几乎看不到交换区中有任何东西,只有偶尔有几 MB 空间,然后不久后这个问题就出现了。我不太有根据的猜测是,它与磁盘缓存太贪婪或内存管理太宽松有关,因此当需要内存时,它不能足够快地释放,导致系统资源匮乏。
如果处理加载到磁盘缓存中的大文件(500MB+),问题就会很快出现,显然之后系统无法足够快地卸载它们。
任何帮助或想法都将不胜感激。
现在我不得不生活在恐惧之中,当做某件事的时候,电脑就会死机,我通常不得不重新启动它,如果它真的耗尽了内存,我更希望它能杀死一些用户空间应用程序,比如浏览器(最好是我能以某种方式标记先杀死哪个)
尽管令人费解的是,为什么在这种情况下 swap 不能拯救我。
更新:它有一段时间没有挂起,但现在又出现了几次。我现在一直在屏幕上显示内存监视器,当挂起发生时,它仍然显示约 30% 的可用空间(可能由磁盘缓存使用)。其他症状:如果当时我正在观看视频(VLC 播放器),声音会先停止,几秒钟后图像会停止。虽然声音停止了,但我仍然可以控制 PC,但是当图像停止时,我甚至无法再移动鼠标,因此等待了一段时间后我重新启动了它。顺便说一句,这不是在我开始观看视频时发生的,而是在某个时间(20 分钟)后发生的,当时我并没有主动做任何其他事情,即使浏览器和 oowrite 一直在第二个屏幕上打开。基本上,某件事只是决定在某一时刻发生并导致系统挂起。
根据评论中的要求,我dmesg
在挂起后立即运行。我没有注意到任何奇怪的事情,但不知道该看什么,所以这里是:
https://docs.google.com/document/d/1iQih0Ee2DwsGd3VuQZu0bPbg0JGjSOCRZhu0B05CMYs/edit?hl=en_US&authkey=CPzF7bcC
答案1
为了解决这个问题,我发现你需要将以下设置设置为总物理 RAM 的 5%-6% 左右,除以计算机的核心数:
sysctl -w vm.min_free_kbytes=65536
请记住,这是每个核心的设置,所以如果我有 2GB RAM 和两个核心,那么我计算只有 1 GB 的 6% 并添加了一些额外的以确保安全。
这会强制计算机尝试保持此数量的 RAM 空闲,从而限制了缓存磁盘文件的能力。当然,它仍会尝试缓存它们并立即将它们交换出去,因此您可能也应该限制交换:
sysctl -w vm.swappiness=5
(100 = 尽可能频繁地交换,0 = 仅在绝对必要时交换)
结果是,Linux 不再在观看电影时随机决定在 RAM 中加载约 1GB 的整个电影文件,并因此导致机器死亡。
现在有足够的保留空间来避免内存不足,这显然是问题所在(因为不再像以前那样出现冻结)。
经过一天的测试后,死机现象消失了,有时会出现轻微的速度减慢,因为内容被更频繁地缓存,但如果我不必每隔几个小时重新启动计算机,我可以忍受。
这里的教训是 - 默认内存管理只是用例之一,并不总是最好的,即使有些人试图提出相反的建议 - 家庭娱乐 ubuntu 的配置应该与服务器不同。
您可能希望通过/etc/sysctl.conf
如下方式将这些设置添加到您的设置中以使它们永久生效:
vm.swappiness=5
vm.min_free_kbytes=65536
答案2
我在新安装的 Ubuntu 14.04 中遇到了这种情况。
就我而言,它与提到的 sysctl 问题无关。
相反,问题在于安装期间交换分区的 UUID 与安装后不同。所以我的交换分区从未启用过,我的机器在使用几个小时后就会锁定。
这解决方案检查交换分区的当前 UUID 是
sudo blkid
然后sudo nano /etc/fstab
用 blkid 报告的 UUID 值替换错误的交换的 UUID 值。
简单的重启即可使更改生效,瞧!
答案3
对我没什么用!!
所以我写了一个脚本来监控内存使用情况。如果内存消耗超过阈值,它将首先尝试清除 RAM 缓存。您可以在脚本上配置此阈值。如果内存消耗仍未低于阈值,它将开始按内存消耗的递减顺序逐个终止进程,直到内存消耗低于阈值。我默认将其设置为 96%。您可以通过更改脚本中变量 RAM_USAGE_THRESHOLD 的值来配置它。
我同意,终止消耗大量内存的进程并不是完美的解决方案,但最好终止一个应用程序,而不是丢失所有工作!如果 RAM 使用率增加阈值,脚本将向您发送桌面通知。如果它终止任何进程,它也会通知您。
#!/usr/bin/env python
import psutil, time
import tkinter as tk
from subprocess import Popen, PIPE
import tkinter
from tkinter import messagebox
root = tkinter.Tk()
root.withdraw()
RAM_USAGE_THRESHOLD = 96
MAX_NUM_PROCESS_KILL = 100
def main():
if psutil.virtual_memory().percent >= RAM_USAGE_THRESHOLD:
# Clear RAM cache
mem_warn = "Memory usage critical: {}%\nClearing RAM Cache".\
format(psutil.virtual_memory().percent)
print(mem_warn)
Popen("notify-send \"{}\"".format(mem_warn), shell=True)
print("Clearing RAM Cache")
print(Popen('echo 1 > /proc/sys/vm/drop_caches',
stdout=PIPE, stderr=PIPE,
shell=True).communicate())
post_cache_mssg = "Memory usage after clearing RAM cache: {}%".format(
psutil.virtual_memory().percent)
Popen("notify-send \"{}\"".format(post_cache_mssg), shell=True)
print(post_cache_mssg)
if psutil.virtual_memory().percent < RAM_USAGE_THRESHOLD:
print("Clearing RAM cache saved the day")
return
# Kill top C{MAX_NUM_PROCESS_KILL} highest memory consuming processes.
ps_killed_notify = ""
for i, ps in enumerate(sorted(psutil.process_iter(),
key=lambda x: x.memory_percent(),
reverse=True)):
# Do not kill root
if ps.pid == 1:
continue
elif (i > MAX_NUM_PROCESS_KILL) or \
(psutil.virtual_memory().percent < RAM_USAGE_THRESHOLD):
messagebox.showwarning('Killed proccess - save_hang',
ps_killed_notify)
Popen("notify-send \"{}\"".format(ps_killed_notify), shell=True)
return
else:
try:
ps_killed_mssg = "Killed {} {} ({}) which was consuming {" \
"} % memory (memory usage={})". \
format(i, ps.name(), ps.pid, ps.memory_percent(),
psutil.virtual_memory().percent)
ps.kill()
time.sleep(1)
ps_killed_mssg += "Current memory usage={}".\
format(psutil.virtual_memory().percent)
print(ps_killed_mssg)
ps_killed_notify += ps_killed_mssg + "\n"
except Exception as err:
print("Error while killing {}: {}".format(ps.pid, err))
else:
print("Memory usage = " + str(psutil.virtual_memory().percent))
root.update()
if __name__ == "__main__":
while True:
try:
main()
except Exception as err:
print(err)
time.sleep(1)
将代码保存在文件中,例如 save_hang.py。运行脚本如下:
sudo python save_hang.py
请注意,此脚本仅与 Python 3 兼容,并且需要您安装 tkinter 包。您可以按如下方式安装它:
sudo apt-get install python3-tk
希望这可以帮助...
答案4
我的猜测是,您将您的vm.swappiness
值设置得太低,这导致内核交换得太晚,导致系统无法使用太低的 RAM。
您可以通过执行以下命令显示当前的 swappiness 设置:
sysctl vm.swappiness
默认情况下,该值设置为 60。Ubuntu 维基建议将其设置为 10,但也可以将其设置为更高的值。您可以通过运行以下命令来更改它:
sudo sysctl vm.swappiness=10
这将改变它仅限当前会话,为了使其持久,您需要添加vm.swappiness = 10
到/etc/sysctl.conf
文件中。
如果您的磁盘速度很慢,请考虑购买一个新的。