使用on_event时Bokeh Server出现内存泄漏问题
问题原因与解决方案
核心问题:无限事件循环
你遇到的内存泄漏和崩溃,本质是无限事件循环导致的:
- 用户缩放图表触发
RangesUpdate事件后,回调函数更新了数据源的x和y数据 - Bokeh会自动根据新数据调整图表的x轴范围,这又会再次触发
RangesUpdate事件 - 该过程反复执行,导致服务器持续处理事件、占用内存,最终崩溃
- Jupyter环境的事件处理机制存在隐性节流,因此未触发这个循环
解决方法
方法1:更新数据时临时禁用事件监听
在回调函数中先移除事件绑定,更新数据后再重新绑定,避免循环触发:
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource from bokeh.events import RangesUpdate from bokeh.server.server import Server import numpy as np def bkapp(doc): fig = figure() x = np.linspace(-6, 6) y = np.cos(x) source = ColumnDataSource({"x": x, "y": y}) line = fig.line("x", "y", source=source) def ranges_update(event): # 临时移除事件监听 fig.remove_on_event(RangesUpdate, ranges_update) # 更新数据(直接替换data比update更高效) x_new = np.linspace(event.x0, event.x1) y_new = np.cos(x_new) line.data_source.data = {"x": x_new, "y": y_new} # 重新绑定事件 fig.on_event(RangesUpdate, ranges_update) fig.on_event(RangesUpdate, ranges_update) doc.add_root(fig) server = Server(bkapp, num_procs=1) server.start() server.io_loop.add_callback(server.show, "/") server.io_loop.start()
方法2:手动固定x轴范围,禁止自动调整
更新数据后手动设置x轴范围,阻止Bokeh自动调整范围触发新事件:
def ranges_update(event): x_new = np.linspace(event.x0, event.x1) y_new = np.cos(x_new) line.data_source.data = {"x": x_new, "y": y_new} # 手动设置x轴范围,覆盖自动调整 fig.x_range.start = event.x0 fig.x_range.end = event.x1
方法3:改用前端CustomJS回调(无需服务器参与)
如果逻辑不需要Python处理,直接用前端回调可完全避免服务器端循环问题:
from bokeh.models import CustomJS def bkapp(doc): fig = figure() x = np.linspace(-6, 6) y = np.cos(x) source = ColumnDataSource({"x": x, "y": y}) line = fig.line("x", "y", source=source) # 前端回调,直接在浏览器中执行 callback = CustomJS(args=dict(source=source), code=""" const x0 = cb_obj.x_range.start; const x1 = cb_obj.x_range.end; const x = Array.from({length: 50}, (_, i) => x0 + (x1 - x0)*i/49); const y = x.map(v => Math.cos(v)); source.data = {x, y}; // 手动固定范围 cb_obj.x_range.start = x0; cb_obj.x_range.end = x1; """) fig.x_range.js_on_change('start', callback) fig.x_range.js_on_change('end', callback) doc.add_root(fig)
内容的提问来源于stack exchange,提问作者Davide_sd
相关产品推荐
相关产品推荐

