基于Python編寫個自用的內(nèi)存清理工具
開發(fā)背景
自己電腦經(jīng)常內(nèi)存飆升卻不知道是什么進(jìn)程引起的,按傳統(tǒng)辦法是要點開任務(wù)管理器去排個序來查看下,有時還要點開文件位置再確認(rèn)一下,覺得麻煩。 于是干脆用Python寫一個,很實用!
功能特點
內(nèi)存清理信息:清理前和清理后的內(nèi)存使用總和。
進(jìn)程列表:顯示所有進(jìn)程的 PID、名稱、內(nèi)存使用和文件位置。點擊列名可以對該列進(jìn)行排序。
功能按鈕:清理內(nèi)存”:清理內(nèi)存并更新內(nèi)存使用信息。“刷新進(jìn)程列表”:重新加載進(jìn)程列表并更新內(nèi)存使用信息。“結(jié)束進(jìn)程”:彈出確認(rèn)對話框,用戶確認(rèn)后結(jié)束選中的進(jìn)程。“導(dǎo)出進(jìn)程列表”:將當(dāng)前進(jìn)程列表導(dǎo)出為 CSV 文件。
新進(jìn)程提醒:如果有新進(jìn)程啟動,會彈窗顯示進(jìn)程的名稱、PID 和文件位置。
工具截圖
完整代碼
import os import psutil import ctypes import sys import tkinter as tk from tkinter import ttk, messagebox, filedialog import csv import time import threading # 檢查并提升管理員權(quán)限 def run_as_admin(): if sys.platform != 'win32': return False try: if ctypes.windll.shell32.IsUserAnAdmin(): return True except: pass ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1) sys.exit() # 獲取所有進(jìn)程信息 def get_processes(): processes = [] for proc in psutil.process_iter(['pid', 'name', 'memory_info', 'exe']): try: processes.append((proc.info['pid'], proc.info['name'], proc.info['memory_info'].rss, proc.info['exe'])) except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): continue return processes # 計算所有進(jìn)程的內(nèi)存使用總和 def get_total_memory_usage(): total_memory = 0 for proc in psutil.process_iter(['memory_info']): try: total_memory += proc.info['memory_info'].rss except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): continue return total_memory # 結(jié)束選中的進(jìn)程 def kill_process(): selected_item = process_tree.selection() if not selected_item: messagebox.showwarning("警告", "請選擇一個進(jìn)程!") return pid = int(process_tree.item(selected_item, 'values')[0]) process_name = process_tree.item(selected_item, 'values')[1] # 確認(rèn)對話框 confirm = messagebox.askyesno("確認(rèn)", f"確定要結(jié)束進(jìn)程 {process_name} (PID: {pid}) 嗎?") if not confirm: return try: process = psutil.Process(pid) process.terminate() messagebox.showinfo("成功", f"進(jìn)程 {process_name} (PID: {pid}) 已結(jié)束!") refresh_processes() except Exception as e: messagebox.showerror("錯誤", f"結(jié)束進(jìn)程時出錯: {e}") # 刷新進(jìn)程列表 def refresh_processes(): for row in process_tree.get_children(): process_tree.delete(row) processes = get_processes() for proc in processes: process_tree.insert("", "end", values=proc) # 更新內(nèi)存使用信息 update_memory_usage() # 更新內(nèi)存使用信息 def update_memory_usage(): total_memory = get_total_memory_usage() memory_before.set(f"清理前內(nèi)存使用: {total_memory / 1024 / 1024:.2f} MB") memory_after.set(f"清理后內(nèi)存使用: {total_memory / 1024 / 1024:.2f} MB") # 內(nèi)存清理功能 def clear_memory(): try: # 獲取清理前的內(nèi)存使用總和 before_memory = get_total_memory_usage() # 釋放未使用的內(nèi)存 ctypes.windll.psapi.EmptyWorkingSet(ctypes.c_ulong(-1)) # 獲取清理后的內(nèi)存使用總和 after_memory = get_total_memory_usage() # 更新界面顯示 memory_before.set(f"清理前內(nèi)存使用: {before_memory / 1024 / 1024:.2f} MB") memory_after.set(f"清理后內(nèi)存使用: {after_memory / 1024 / 1024:.2f} MB") messagebox.showinfo("成功", "內(nèi)存清理完成!") except Exception as e: messagebox.showerror("錯誤", f"清理內(nèi)存時出錯: {e}") # 導(dǎo)出進(jìn)程列表為 CSV 文件 def export_processes(): file_path = filedialog.asksaveasfilename( defaultextension=".csv", filetypes=[("CSV 文件", "*.csv"), ("所有文件", "*.*")], title="保存進(jìn)程列表" ) if not file_path: return try: with open(file_path, mode="w", newline="", encoding="utf-8") as file: writer = csv.writer(file) # 寫入表頭 writer.writerow(["PID", "進(jìn)程名", "內(nèi)存使用 (MB)", "文件位置"]) # 寫入進(jìn)程數(shù)據(jù) for row in process_tree.get_children(): values = process_tree.item(row, 'values') writer.writerow(values) messagebox.showinfo("成功", f"進(jìn)程列表已導(dǎo)出到 {file_path}") except Exception as e: messagebox.showerror("錯誤", f"導(dǎo)出進(jìn)程列表時出錯: {e}") # 排序函數(shù) def treeview_sort_column(tv, col, reverse): l = [(tv.set(k, col), k) for k in tv.get_children('')] try: l.sort(key=lambda t: int(t[0]) if col == "memory" else t[0], reverse=reverse) except ValueError: l.sort(reverse=reverse) for index, (val, k) in enumerate(l): tv.move(k, '', index) tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse)) # 監(jiān)控新進(jìn)程 def monitor_new_processes(): global previous_processes while True: current_processes = get_processes() current_pids = {proc[0] for proc in current_processes} previous_pids = {proc[0] for proc in previous_processes} # 檢查新進(jìn)程 new_pids = current_pids - previous_pids if new_pids: for proc in current_processes: if proc[0] in new_pids: messagebox.showinfo( "新進(jìn)程提醒", f"新進(jìn)程已啟動:\n\n" f"進(jìn)程名: {proc[1]}\n" f"PID: {proc[0]}\n" f"文件位置: {proc[3]}" ) previous_processes = current_processes time.sleep(5) # 每 5 秒檢查一次 # 創(chuàng)建主窗口 def create_gui(): global memory_before, memory_after, process_tree, previous_processes root = tk.Tk() root.title("內(nèi)存清理工具") root.geometry("800x600") # 初始化進(jìn)程列表 previous_processes = get_processes() # 啟動新進(jìn)程監(jiān)控線程 monitor_thread = threading.Thread(target=monitor_new_processes, daemon=True) monitor_thread.start() # 標(biāo)題 title_label = tk.Label(root, text="Windows 內(nèi)存清理工具", font=("Arial", 16)) title_label.pack(pady=10) # 內(nèi)存信息顯示 memory_before = tk.StringVar() memory_after = tk.StringVar() memory_before.set("清理前內(nèi)存使用: N/A") memory_after.set("清理后內(nèi)存使用: N/A") before_label = tk.Label(root, textvariable=memory_before, font=("Arial", 12)) before_label.pack(pady=5) after_label = tk.Label(root, textvariable=memory_after, font=("Arial", 12)) after_label.pack(pady=5) # 清理內(nèi)存按鈕 clear_button = tk.Button(root, text="清理內(nèi)存", command=clear_memory, font=("Arial", 14), bg="lightblue") clear_button.pack(pady=10) # 進(jìn)程列表 process_frame = tk.Frame(root) process_frame.pack(fill="both", expand=True, padx=10, pady=10) columns = ("pid", "name", "memory", "exe") process_tree = ttk.Treeview(process_frame, columns=columns, show="headings") process_tree.heading("pid", text="PID", command=lambda: treeview_sort_column(process_tree, "pid", False)) process_tree.heading("name", text="進(jìn)程名", command=lambda: treeview_sort_column(process_tree, "name", False)) process_tree.heading("memory", text="內(nèi)存使用 (MB)", command=lambda: treeview_sort_column(process_tree, "memory", False)) process_tree.heading("exe", text="文件位置", command=lambda: treeview_sort_column(process_tree, "exe", False)) process_tree.column("pid", width=100, anchor="center") process_tree.column("name", width=200, anchor="w") process_tree.column("memory", width=150, anchor="center") process_tree.column("exe", width=300, anchor="w") process_tree.pack(fill="both", expand=True) # 刷新進(jìn)程列表按鈕 refresh_button = tk.Button(root, text="刷新進(jìn)程列表", command=refresh_processes, font=("Arial", 12), bg="lightgreen") refresh_button.pack(pady=10) # 結(jié)束進(jìn)程按鈕 kill_button = tk.Button(root, text="結(jié)束進(jìn)程", command=kill_process, font=("Arial", 12), bg="lightcoral") kill_button.pack(pady=10) # 導(dǎo)出進(jìn)程列表按鈕 export_button = tk.Button(root, text="導(dǎo)出進(jìn)程列表", command=export_processes, font=("Arial", 12), bg="lightyellow") export_button.pack(pady=10) # 初始化進(jìn)程列表和內(nèi)存使用信息 refresh_processes() root.mainloop() if __name__ == "__main__": run_as_admin() create_gui()
代碼說明
1.monitor_new_processes:
這是一個后臺線程函數(shù),每 5 秒檢查一次系統(tǒng)進(jìn)程列表。
如果發(fā)現(xiàn)新進(jìn)程,彈窗顯示進(jìn)程的名稱、PID 和文件位置。
2.get_processes:
獲取所有進(jìn)程的信息,包括 PID、名稱、內(nèi)存使用和文件位置。
3.previous_processes:
用于存儲上一次檢查時的進(jìn)程列表,以便與新進(jìn)程列表進(jìn)行比較。
4.threading.Thread:
使用線程運行 monitor_new_processes,避免阻塞主界面。
到此這篇關(guān)于基于Python編寫個自用的內(nèi)存清理工具的文章就介紹到這了,更多相關(guān)Python內(nèi)存清理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談Python中函數(shù)的定義及其調(diào)用方法
今天小編就為大家分享一篇淺談Python中函數(shù)的定義及其調(diào)用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07Python應(yīng)用實現(xiàn)雙指數(shù)函數(shù)及擬合代碼實例
這篇文章主要介紹了Python應(yīng)用實現(xiàn)雙指數(shù)函數(shù)及擬合代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06詳解windows python3.7安裝numpy問題的解決方法
這篇文章主要介紹了windows python3.7安裝numpy問題的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08在Django中動態(tài)地過濾查詢集的實現(xiàn)
本文主要介紹了Django中動態(tài)地過濾查詢集的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03