Created
August 1, 2024 08:06
-
-
Save infibrocco/e974fb9b16c2f43dbf9ff855b0b17ce2 to your computer and use it in GitHub Desktop.
simple python program to check for high memory usage processes and optionally killing them
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import psutil | |
def check_high_memory_usage(threshold=90): | |
""" | |
Check for processes using more than the specified threshold of memory. | |
Args: | |
threshold (int): The memory usage percentage threshold. Default is 90. | |
Returns: | |
list: A list of dictionaries with process info for those exceeding the threshold. | |
""" | |
processes = [] | |
for proc in psutil.process_iter(["pid", "name", "memory_percent"]): | |
try: | |
# Check if process memory usage is above the threshold | |
if proc.info["memory_percent"] > threshold: | |
processes.append(proc.info) | |
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): | |
# Ignore processes that no longer exist or can't be accessed | |
pass | |
return processes | |
def kill_procs(procs, safely=True): | |
""" | |
Terminate or kill the specified processes. | |
Args: | |
procs (list): A list of dictionaries with process info. | |
safely (bool): If True, try to terminate first and then kill if needed. | |
If False, kill immediately. | |
""" | |
procs = [psutil.Process(p["pid"]) for p in procs] | |
if safely: | |
for p in procs: | |
# Attempt to terminate the process | |
p.terminate() | |
# Wait for processes to terminate, then kill any that remain | |
gone, alive = psutil.wait_procs( | |
procs, timeout=2, callback=lambda p: print(f"process {p} terminated safely") | |
) | |
for p in alive: | |
p.kill() | |
print("killed", p) | |
else: | |
# Kill processes immediately | |
for p in procs: | |
p.kill() | |
print(f"process {p} killed") | |
def main(): | |
""" | |
Main function to parse arguments and check for high memory usage processes. | |
Optionally kills processes that exceed the memory usage threshold. | |
""" | |
import argparse | |
from time import sleep | |
parser = argparse.ArgumentParser(description="checks for high memory usage processes and optionally kills them if they exceed the memory usage threshold") | |
parser.add_argument( | |
"-m", type=int, default=90, help="Memory usage threshold percentage" | |
) | |
parser.add_argument("-c", action="store_true", help="Continuous mode") | |
parser.add_argument("-k", action="store_true", help="Kill mode") | |
parser.add_argument( | |
"--unsafe", action="store_true", help="Use unsafe kill (SIGKILL) immediately" | |
) | |
args = parser.parse_args() | |
if args.k: | |
print( | |
f"Process kill mode is on. Will kill any process that exceeds {args.m}% of RAM usage. " | |
+ ( | |
"(sends SIGTERM and later SIGKILL if it's unresponsive)" | |
if not args.unsafe | |
else "(sends SIGKILL)" | |
) | |
) | |
high_memory_processes = check_high_memory_usage(threshold=args.m) | |
if high_memory_processes: | |
if args.k: | |
# Kill the processes if kill mode is enabled | |
kill_procs(high_memory_processes, safely=not args.unsafe) | |
print(f"Offenders (using more than {args.m}% of RAM):") | |
for proc in high_memory_processes: | |
print( | |
f"PID: {proc['pid']}, Name: {proc['name']}, Memory Usage: {proc['memory_percent']:.2f}%" | |
) | |
else: | |
print(f"No processes are using more than {args.m}% of RAM.") | |
if args.c: | |
# Continuous mode to repeatedly check for high memory usage processes | |
print("Initiating continuous mode...") | |
print(f"Offenders (using more than {args.m}% of RAM):") | |
while True: | |
procs = check_high_memory_usage(threshold=args.m) | |
if args.k: | |
kill_procs(procs, safely=not args.unsafe) | |
if procs: | |
print( | |
"\n".join( | |
f"PID: {proc['pid']}, Name: {proc['name']}, Memory Usage: {proc['memory_percent']:.2f}%" | |
for proc in procs | |
) | |
) | |
sleep(3) | |
if __name__ == "__main__": | |
try: | |
main() | |
except KeyboardInterrupt: | |
print("\rGracefully exiting...") | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment