Skip to content

Instantly share code, notes, and snippets.

@infibrocco
Created August 1, 2024 08:06
Show Gist options
  • Save infibrocco/e974fb9b16c2f43dbf9ff855b0b17ce2 to your computer and use it in GitHub Desktop.
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
#!/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