You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:39:02