如何修复Python Kivy文件夹监控应用内存占用过高崩溃问题
问题根因
你代码的内存溢出和崩溃问题由以下几个错误导致:
watchdog1.py里多余的无限while True死循环:Watchdog的Observer本身就是独立后台线程,调用start()后会自动在后台运行,不需要额外加死循环阻塞线程- 没有合理管理监控实例:你导入了
_thread但完全没有使用,直接调用watch()函数时死循环会阻塞Kivy主UI线程,持续占用内存 - 没有释放监控资源:取消文件夹勾选时没有停止对应
Observer实例,重复勾选会重复创建新的监控实例,大量实例堆积最终导致内存溢出 - 代码不规范问题:
MainApp的build()方法没有返回主窗口实例,属于不符合Kivy规范的写法
修复后的代码
1. watchdog1.py 代码修改
import logging from watchdog.observers import Observer from watchdog.events import LoggingEventHandler def watch(p): logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') path = p event_handler = LoggingEventHandler() observer = Observer() observer.schedule(event_handler, path, recursive=True) observer.start() # 移除多余的死循环,直接返回observer实例方便后续停止 return observer
2. main.py 代码修改
from kivy.app import App from kivy.core.window import Window from kivy.uix.anchorlayout import AnchorLayout from kivy.uix.label import Label from kivy.uix.checkbox import CheckBox from kivy.uix.boxlayout import BoxLayout from kivy.clock import Clock from kivy.properties import ObjectProperty from watchdog1 import watch WIDTH, HEIGHT = 1000, 800 class MainWindow(AnchorLayout): bbox = ObjectProperty(None) folders = ["Desktop", "Documents", "Downloads"] bools = {} # 新增字典存储每个文件夹对应的observer实例 observers = {} def __init__(self, **kwargs): super().__init__(**kwargs) Clock.schedule_once(self.add_initial, .1) Clock.schedule_interval(self.check_active, .1) def add_initial(self, dt): for f in self.folders: self.add_folder(f) def add_folder(self, text): f = Label(text=text) s = CheckBox() b = BoxLayout() b.add_widget(f) b.add_widget(s) self.bbox.add_widget(b) self.bools[text] = 0 def check_active(self, dt): for widget in self.bbox.children: t = widget.children[1].text b = widget.children[0].active if b is True and self.bools[t] == 0: print(t, "is active") # 启动监控,存储observer实例 self.observers[t] = watch(f"C:/Users/Chris/{t}") self.bools[t] = 1 elif b is False and self.bools[t] == 1: # 取消勾选时停止对应监控,释放资源 if t in self.observers: self.observers[t].stop() self.observers[t].join() del self.observers[t] self.bools[t] = 0 class MainApp(App): def build(self): Window.size = (WIDTH, HEIGHT) self.title = "Kivy Watchdog" # 补全返回主窗口实例的逻辑 return MainWindow() if __name__ == "__main__": MainApp().run()
3. main.kv 代码无需修改,可正常使用
修复后效果
- 不会再出现主线程阻塞问题
- 取消勾选时会自动释放监控资源,不会出现实例堆积
- 内存占用稳定,不会出现运行1分钟后崩溃的问题
内容的提问来源于stack exchange,提问作者user16414459
相关产品推荐
相关产品推荐

