Назад | Перейти на главную страницу

Убейте самый требовательный к памяти процесс, когда память становится мало [closed]

Иногда на моем настольном компьютере, ноутбуке или сервере 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%, процесс, выбранный этим сценарием, может завершиться вовремя.