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

Tkinter定时绘图函数触发Out of memory错误,程序崩溃求助

内存泄漏问题排查与修复

你的代码运行一段时间后触发内存溢出,核心原因是每次调用plot时都重复创建新的Matplotlib绘图对象和Tkinter组件,旧对象未被彻底清理,导致内存堆积,以下是具体问题和修复方案:

核心问题点

  • 每次销毁重建plot_frame,并创建新的Figure、FigureCanvasTkAgg,旧对象的引用未被完全清除,持续占用内存
  • 误用plt.clf():你创建的是独立的self.fig,但plt.clf()操作的是Matplotlib全局的当前Figure,无法清理你自己创建的self.fig中的旧绘图元素
  • 直接修改类属性Simulation.ax:每次调用都会覆盖这个类级别的属性,旧的Axes对象因被类引用无法被垃圾回收
  • 未主动清理旧canvas:新创建self.canvas后,旧实例若仍被引用,会留在内存中无法释放

修复后的代码

def plot(self):
    # 复用plot_frame,无需每次销毁重建
    if not hasattr(self, 'plot_frame') or self.plot_frame is None:
        self.plot_frame = tk.Frame(self, bg=self.bg)
        self.plot_frame.pack(fill="both", expand=True)
    
    # 复用Figure和Axes,避免重复创建新对象
    if not hasattr(self, 'fig') or self.fig is None:
        self.fig = plt.Figure()
        self.ax = self.fig.add_subplot(111)
        self.ax.set_title("Damage Accumulation Curve")
        self.ax.set_xlabel("Load Case")
        self.ax.set_ylabel("Accumulative Fatigue Damage")
        # 初始化canvas并挂载到frame
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.plot_frame)
        self.canvas.get_tk_widget().pack(fill="both", expand=True)
    else:
        # 清理当前Axes的旧绘图内容
        self.ax.clear()
        # 重置标题和坐标轴标签(clear操作会清除这些配置)
        self.ax.set_title("Damage Accumulation Curve")
        self.ax.set_xlabel("Load Case")
        self.ax.set_ylabel("Accumulative Fatigue Damage")
    
    # 简化数据处理逻辑(原代码中重复切片无意义)
    x_axis = np.arange(0, len(Simulation.accumulated))
    x = x_axis[-10:]
    y = np.array(Simulation.accumulated[-10:])
    
    # 在复用的Axes上绘制新数据
    self.ax.plot(x, y)
    
    # 更新canvas显示
    self.canvas.draw()
    
    # 更新控件值
    self.graph_theta.set(Simulation.theta)
    self.graph_arcl.set(Simulation.arcl)
    
    # 继续定时调用
    self.after(30000, self.plot)

额外优化建议

  • 避免修改类属性Simulation.ax:如果Simulation是实例,改用实例属性(如sim_instance.ax);若必须用类属性,赋值前先执行del Simulation.ax解除旧对象引用
  • 手动触发垃圾回收:在绘图完成后添加import gc; gc.collect(),帮助及时释放无引用的对象
  • 控制Simulation.accumulated大小:如果这个列表持续增长,会占用大量内存,建议定期清理历史数据(比如只保留最近100个数据点)

内容的提问来源于stack exchange,提问作者user1821998

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:45:17