跳转至

Agent 服务跑了一段时间后内存持续增长,你怎么排查和解决?

每个做过长稳服务的应该都踩过坑。我按“现象 → 定位 → 分析 → 根治”这条线讲,中间画一个排查路线图,最后说一套我固定的防护清单。


🔍 现象确认:不是内存抖动,是持续增长

上来先别急着动手,得区分两种涨法:

  • 锯齿形:请求来了涨,请求结束跌回去,是正常的工作内存。

  • 阶梯形:每处理一批请求就涨一个台阶,从不回落,这才是泄漏。

快速确认:用 psutil.Process().memory_info().rss 打点,每隔 10 秒记一次,画个折线图,斜率一直正的就是有问题。


🧭 排查路线图(我用脑图的形式画出来)

image.png

🛠️ 实际怎么定位(以我最近一个 Agent 为例)

Step 1:起一个 tracemalloc 对比

import tracemalloc
tracemalloc.start()
# ... 跑 100 轮对话 ...
snapshot = tracemalloc.take_snapshot()
# 再跑 100 轮
snapshot2 = tracemalloc.take_snapshot()
stats = snapshot2.compare_to(snapshot, 'lineno')
for s in stats[:5]:
    print(s)

立刻看到 Top1 是某个 messages 列表的大小在疯长。

Step 2:查谁在抓着这个列表不放 用 gc.get_referrers()objgraph.show_backrefs() 画出来:

import objgraph
obj = problematic_messages_list
objgraph.show_backrefs([obj], max_depth=5, filename='chain.png')

结果发现链是:messages_listdictTool 实例 → Tool.initself.callback = lambda: messages_list 形成的闭包循环。这个 Tool 实例又因为放在全局 ACTIVE_TOOLS 里,永远不释放。

Step 3:验证修复 把全局 dict 换成 WeakValueDictionary,把闭包改成 weakref.ref(messages_list) 后回调时先解引用判空。再跑相同压测,tracemalloc 对比差值归零。