LOGO 首页 OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 技术文档 其他文档  
 
网站管理员

[点晴永久免费OA]一次Python内存泄漏的真实排查经历

zhenglin
2026年6月3日 8:57 本文热度 66

上周线上服务内存占用一路飙升,从200MB涨到2GB,最后OOM被系统杀了。排查过程挺曲折的,分享一下,希望帮到踩类似坑的朋友。

现象

监控告警,服务内存持续增长,重启后从200MB开始,几小时后又到2GB。典型的内存泄漏特征。

排查过程

第一步:确认是不是真的泄漏

先用tracemalloc追踪内存分配:

import tracemalloc

tracemalloc.start()


# ... 运行业务代码 ...


snapshot = tracemalloc.take_snapshot()

top_stats = snapshot.statistics('lineno')

for stat in top_stats[:10]:

    print(stat)

输出显示某个字典对象一直在增长,占用从几MB涨到了几百MB。

第二步:定位问题代码

追了一下,发现是一个全局缓存字典没有淘汰机制:

# 问题代码:缓存只进不出

_user_cache = {}


def get_user(user_id):

    if user_id not in _user_cache:

        _user_cache[user_id] = fetch_user_from_db(user_id)

    return _user_cache[user_id]

看起来没问题对吧?但我们的场景是用户量很大,每个用户第一次访问就缓存了,之后永远不会清理。随着用户访问越来越多,缓存就越积越大。

第三步:修复

最简单的方案,换成LRU缓存:

from functools import lru_cache


@lru_cache(maxsize=10000)

def get_user(user_id):

    return fetch_user_from_db(user_id)

加了maxsize后,缓存超过10000条就自动淘汰最久没访问的。内存占用稳定在300MB左右,问题解决。

反思

其实这个坑很低级,但当时写代码的时候确实没想到用户量会到这个级别。几个教训:

  1. 全局缓存一定要有淘汰策略,不管你用lru_cachecachetools.TTLCache还是Redis,总之不能只进不出

  2. 上线前做一下内存压测,模拟一段时间的持续请求,看内存是否持续增长

  3. tracemalloc是排查Python内存问题的利器,比凭直觉猜靠谱多了

顺便说一句,如果缓存的数据来自API调用,还要考虑缓存过期的问题。之前我有个项目调大模型API,结果缓存了过期的响应,debug了好久才反应过来。国内用这些API有时候响应慢或者不稳定,我后来换了个中转站,响应速度好了不少,缓存命中率也提上去了。


阅读原文


该文章在 2026/6/3 8:57:06 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-2  粤公网安备44030602007207号