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

含全局变量的Python循环脚本内存持续增长问题排查

问题根源

你遇到的内存泄漏问题,核心原因在于**go.FigureWidget的设计特性**:它是为Jupyter交互式环境开发的组件,内部会持有额外的资源(比如事件监听、ipywidgets关联的底层引用),这些资源不会被Python的自动垃圾回收机制完全清理——哪怕你删除了对figs_all的引用,旧的FigureWidget实例仍可能残留未释放的内存。

解决方案

针对你的场景,最彻底的解决办法是替换组件类型,或者手动清理资源,具体如下:

1. 改用普通go.Figure(推荐)

Dash应用本身自带交互回调能力,完全不需要依赖FigureWidget的交互式特性。直接替换为普通go.Figure,可以彻底避免额外资源绑定导致的内存泄漏:

import sys
import time
import gc
import numpy as np
import plotly.graph_objects as go
    
def load_data():
    global figs_all
    
    Npts = 100000
    Nplots = 100
    Nsubplots = 5
    
    # 先清理旧变量引用
    if 'figs_all' in globals():
        del figs_all
    figs_all = {}
    
    for ii in range(0,Nplots):
        title = str(ii)
        print(title)
        # 替换为普通go.Figure
        fig = go.Figure(layout={'width': 1600, 'height': 800})
        for jj in range(0,Nsubplots):
            xx = np.random.rand(Npts)
            yy = np.random.rand(Npts)
            fig.add_scattergl(x=xx, y=yy, mode='markers', name=title)
        figs_all[title] = fig
    # 手动触发垃圾回收,加速内存释放
    gc.collect()

if __name__ == '__main__':
    load_data()
    while 1:
        time.sleep(1)
        load_data()

2. 若必须保留FigureWidget,手动清理资源

如果你的场景确实需要FigureWidget,则需要在替换全局变量前,主动调用每个实例的close()方法,释放其持有的底层资源:

def load_data():
    global figs_all
    
    # 先清理旧的FigureWidget资源
    if 'figs_all' in globals() and figs_all is not None:
        for fig in figs_all.values():
            fig.close()  # 释放FigureWidget的关联资源
        del figs_all
    
    Npts = 100000
    Nplots = 100
    Nsubplots = 5
    
    figs_all = {}
    
    for ii in range(0,Nplots):
        title = str(ii)
        print(title)
        fig = go.FigureWidget(layout={'width': 1600, 'height': 800})
        for jj in range(0,Nsubplots):
            xx = np.random.rand(Npts)
            yy = np.random.rand(Npts)
            fig.add_scattergl(x=xx, y=yy, mode='markers', name=title)
        figs_all[title] = fig
    gc.collect()
补充说明
  • 内存不会立刻回落到初始值是正常现象:Python的垃圾回收有延迟,numpy数组的内存管理也有自身机制,但修改后内存不会再持续攀升。
  • 你的Dash重启逻辑可以保留:结合上述修改后,每次重启前的内存泄漏问题会被解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 19:20:53