• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于python:python内存泄露排查

python 搞代码 3年前 (2022-02-20) 26次浏览 已收录 0个评论

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

1,先确认罪魁祸首:

执行该申请之前之前的虚拟机memory和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更好用写,能够看到增量数据。

pympler

pympler工具能够很容易看到内存的应用状况

guppy

guppy能够查看到heap内存的具体应用状况,哪些对象占用多少内存

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()

把该办法放在可疑代码前后执行

通过前后执行比照发现援用list,dict等对象均有较大减少。而后对代码进行走读,逐渐放大范畴,对可疑代码段进行前后比照,确定最小范畴:

同时对象援用的前后比照也佐证了这一点,如上图。该段代码是基于matplotlib.pyplot绘制一个曲线图,对代码主题性能不影响不是很大,咱们先把该段代码正文掉,再次执行看对象前后援用次数。

通过比照,发现对象援用次数失常了!!!

在服务器部署执行后,比照top信息,执行前:

执行中

执行后

执行实现后内存复原到执行前相当的程度,问题迎刃而解!

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://www.gaodaima.com/quanshengxixin/article/details/68953314

matplotlib内存溢出报错:https://www.gaodaima.com/mym_74/article/details/102887252

利用matplotlib绘制图片,并且将图片保留到文件中。因为没有及时的将内存中的图像革除,以致内存爆表,零碎卡死。

pyplot是一个模块,它收集了一些容许matplotlib以性能形式应用的函数。 我在这里假如pyplot已被导入为“import matplotlib.pyplot as plt”。 在这种状况下,有三个不同的命令能够删除内容:

plt.cla()革除轴,以后流动轴在以后图中。 它放弃其余轴不变。

plt.clf()革除整个以后数字。与所有的轴,但来到窗口关上,这样它就能够再用在其余的 plots上了。

plt.close()关上窗户,如果未另指定,则该窗口将是以后窗口。

因而,哪种性能最适宜您,取决于您的用例。

close()函数还容许指定哪个窗口应该敞开。参数能够是应用figure(number_or_name)创立的窗口的数字或名称。也能够是取得的图形实例,即应用fig = figure()。如果没有人提出任何论点close(),以后流动的窗口将敞开。 此外,还有语法close(’all’),它敞开所有数字。

总结经验,也就是咱们在应用matplotlib.pyplot时,须要在前面追加一个开释操作。

总体来说这是一次因为经验不足导致的犯错,最终解决办法不简单,然而重在问题排查的过程和办法,学到了很多。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于python:python内存泄露排查

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址