首先需要通过系统工具或Python模块验证是否存在内存泄漏。常用方法包括:
top、htop或ps命令观察Python进程的RES(常驻内存)或%MEM(内存占比)是否随时间持续增长(如处理请求后内存未回落)。psutil库获取进程内存详情,对比运行前后的内存变化:import psutil
process = psutil.Process()
print(f"初始内存: {process.memory_info().rss / 1024 / 1024:.2f} MB")
# 运行目标代码
print(f"当前内存: {process.memory_info().rss / 1024 / 1024:.2f} MB")
若内存持续增加且未释放,可能存在泄漏。通过工具追踪内存分配路径和对象引用,找出未被释放的对象:
import tracemalloc
tracemalloc.start()
# 运行目标代码
snapshot1 = tracemalloc.take_snapshot()
# 再次运行或等待一段时间
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(snapshot1, 'lineno')
for stat in top_stats[:10]: # 输出内存增长Top10的代码行
print(stat)
import objgraph
objgraph.show_growth() # 显示各类对象数量增长
objgraph.show_most_common_types(limit=10) # 显示内存中Top10的对象类型
objgraph.show_backrefs(objgraph.by_type('MyClass')[0], filename='refs.png') # 生成引用关系图
from memory_profiler import profile
@profile
def my_function():
# 需要分析的代码
pass
if __name__ == "__main__":
my_function()
运行mprof run script.py后,用mprof plot生成内存使用趋势图。根据定位结果,针对性解决以下常见问题:
weakref模块创建弱引用(不会增加引用计数),或手动断开引用。import weakref
class Node:
def __init__(self):
self.next = None # 改为弱引用
node1 = Node()
node2 = Node()
node1.next = weakref.ref(node2) # 弱引用
node2.next = weakref.ref(node1)
lru_cache装饰器限制缓存大小,或定期清理缓存。from functools import lru_cache
@lru_cache(maxsize=128) # 限制缓存最多128个结果
def expensive_function(x):
return x * x
with语句自动管理资源(上下文管理器),确保资源释放。with open('large_file.txt', 'r') as f: # 自动调用close()
data = f.read()
Python的垃圾回收器(GC)依赖引用计数和分代回收,但循环引用或未及时清理的对象可能导致内存滞留。可通过gc模块手动触发回收:
import gc
gc.collect() # 强制进行垃圾回收
print(f"未被回收的对象: {len(gc.garbage)}") # 查看未被回收的对象数量
注意:频繁手动回收可能影响性能,建议在关键节点(如处理完大批量数据后)使用。
def read_large_file(file_path):
with open(file_path, 'r') as f:
for line in f: # 逐行生成,不占用全部内存
yield line.strip()
array模块替代列表存储数值数据(如array.array('i', range(1000000))),或用collections.deque替代列表实现队列(减少插入/删除的时间复杂度)。若内存泄漏与Python内置的内存分配器(如libc的malloc)有关,可替换为TCMalloc(Thread-Caching Malloc),提升内存分配效率并减少碎片。
libtcmalloc(CentOS):sudo yum install gperftools-libs
libtcmalloc:LD_PRELOAD="/usr/lib64/libtcmalloc.so" python your_script.py
此方法适用于长期运行的Python服务(如Web应用)。通过以上步骤,可系统性地解决CentOS环境下Python程序的内存泄漏问题。关键是先定位泄漏源(通过工具),再针对性修复(修改代码或配置),并结合良好的编程习惯(如及时释放资源、避免全局变量)预防泄漏。