Иногда на моем настольном компьютере, ноутбуке или сервере Linux заканчивается ОЗУ, потому что экспериментальное программное обеспечение, с которым я работаю, иногда пытается использовать больше ОЗУ, чем у меня есть. Когда это происходит, система и консоль зависают на несколько минут, в то время как Linux перемещает память между ОЗУ и свопингом. Похоже, Linux пытается очень трудно предотвратить убийство какой-либо программы, но в моем случае я бы просто хотел, чтобы Linux пошел дальше и убил ее, чтобы я мог вернуться к работе как можно скорее и перезапустить ее без жесткой перезагрузки или ожидания нескольких минут.
Есть ли сторонняя программа, которую я могу запустить в фоновом режиме, которая реализует следующую логику?
when RAM usage is >98%:
kill the process using the most resident RAM
я пробовал sudo sysctl vm.overcommit_memory=2
, но он не делает того, что я считаю лучшим в моей ситуации. Я не хочу убивать небольшие процессы, которые невинно выделяют 1 МБ ОЗУ, когда ОЗУ мало. Я хочу убить единственный процесс, который потребляет 31,9 ГБ ОЗУ или что-то в этом роде, поскольку явно виноват этот процесс, а не маленький процесс.
Также, vm.overcommit_memory
это не то, что я хочу, потому что vm.overcommit_ratio
соответствует соотношению виртуальный память, а не резидент память, деленная на общую физическую память. Таким образом, приложение, которое выделяет 2 ГБ памяти, но не касается каких-либо блоков (и, следовательно, не существует в физической ОЗУ), не должно учитываться в overcommit_ratio.
Я написал быструю реализацию на Python 3.6+ с psutil
библиотека. Вроде отлично работает! Могут быть проблемы, но со временем я их исправлю.
import time
import psutil
percent_threshold = 0.95
def check_memory():
vm = psutil.virtual_memory()
percent = vm.active / vm.total
# Do we need to kill a process?
if percent > percent_threshold:
print(f"RAM usage is {percent}%")
# Search for process using the most resident memory
max_mem = 0
max_ps = None
for ps in psutil.process_iter():
mem = ps.memory_info().rss
if mem > max_mem:
max_ps = ps
max_mem = mem
# Kill process
cmd = " ".join(max_ps.cmdline())
print(f"Killing {cmd}")
print(f"using {max_mem / 2**20} MiB resident memory")
max_ps.terminate()
print("")
while True:
check_memory()
time.sleep(1.0)
terminate()
можно заменить на kill()
для более быстрого уничтожения программы, но завершение будет достаточно быстрым, если пороговое значение установлено на уровне 95%. В то время как программа заполняет последние 5%, процесс, выбранный этим сценарием, может завершиться вовремя.