【Python】python内存泄露排查

最近线上某台虚拟机隔三差五就会挂掉,通过业务日志基本上排查到每次出错都源于某一个请求。于是对该请求展开排查。

1,先确认罪魁祸首:

执行该请求之前之前的虚拟机memory和python进程占用的资源:
【Python】python内存泄露排查

执行一次该请求之后的资源占用情况:
【Python】python内存泄露排查

python占用的资cpu在服务执行过程中会有所提升,但是请求结束后,cpu可以恢复到执行之前的水平;而VIRT,RES,内存占比却有显著提升,且执行完成后并未下降。多次执行,内存占用累积上涨。由此推断,罪魁祸首是该请求,并且可能是由内存泄露引起的。

2,python内存泄露的工具

https://zhmin.github.io/2018/12/22/python-meomory-leak/

通过网上一系列的查找,了解到用于排查python内存泄露的工具有:objgraph,pympler,guppy

objgraph

可以查看对象被引用次数的工具,也可以查看对象调用图。

这里主要用到的方法:

show_most_common_types()

show_growth()

个人觉得show_growth更好用写,可以看到增量数据。
【Python】python内存泄露排查

pympler

pympler工具可以很容易看到内存的使用情况
【Python】python内存泄露排查

guppy

guppy可以查看到heap内存的具体使用情况,哪些对象占用多少内存
【Python】python内存泄露排查

3,代码定位

先写一个记录对象引用次数的方法

import os

import objgraph

def obj_graph_stat(mark=''):

file_path = r'D:\obj_graph.txt'

if not os.path.exists(file_path):

file = open(file_path, 'w')

file.close()

file = open(file_path, 'a')

file.write(f'******************{str(now_datetime())}-{mark}******************\n')

objgraph.show_most_common_types(limit=20, file=file)

file.write(f'-'*20)

file.write('\n')

# 返回heap内存详情

# heap = hp.heap()

# byvia返回该对象的被哪些引用, heap[0]是内存消耗最大的对象

# references = heap[0].byvia

# file.write(str(references))

file.write('\n\n')

file.close()

把该方法放在可疑代码前后执行
【Python】python内存泄露排查
【Python】python内存泄露排查

通过前后执行对比发现引用list,dict等对象均有较大增加。然后对代码进行走读,逐步缩小范围,对可疑代码段进行前后对比,确定最小范围:
【Python】python内存泄露排查

【Python】python内存泄露排查

同时对象引用的前后对比也佐证了这一点,如上图。该段代码是基于matplotlib.pyplot绘制一个曲线图,对代码主题功能不影响不是很大,我们先把该段代码注释掉,再次执行看对象前后引用次数。
【Python】python内存泄露排查

通过对比,发现对象引用次数正常了!!!

在服务器部署执行后,对比top信息,执行前:
【Python】python内存泄露排查

执行中
【Python】python内存泄露排查

【Python】python内存泄露排查

执行后
【Python】python内存泄露排查

执行完成后内存恢复到执行前相当的水平,问题迎刃而解!

4,刨根问底

抓到真凶后,我们总归是好奇,想知道真相的。通过度娘我们发现:

Python循环画图时内存泄露的问题:http://www.biexiaoyu1994.com/%E4%BB%A3%E7%A0%81%E8%B8%A9%E5%9D%91/2019/06/13/python_plot_mem_leak/

matplotlib画图内存爆表:https://blog.csdn.net/quanshengxixin/article/details/68953314

matplotlib内存溢出报错:https://blog.csdn.net/mym_74/article/details/102887252

总结经验,也就是我们在使用matplotlib.pyplot时,需要在后面追加一个释放操作。
【Python】python内存泄露排查

总体来说这是一次由于经验不足导致的犯错,最终解决方法不复杂,但是重在问题排查的过程和方法,学到了很多。

以上是 【Python】python内存泄露排查 的全部内容, 来源链接: utcz.com/a/75072.html

回到顶部