Python实现内存泄露排查的示例

导读

一般在python代码块的调试过程中会使用memory-profiler、filprofiler、objgraph等三种方式进行辅助分析,今天这里主要介绍使用objgraph对象提供的函数接口来进行内存泄露的分析,感兴趣的可以了解一下

一般情况下只有需要长期运行的项目才会去关注内存的增长情况,即使是很小部分的内存泄露经过长期的运行仍然会产生很大的隐患。

python本身也是支持垃圾的自动回收的,但是在特定的情况下也是会出现内存泄露的问题的。

比如对于很多全局的列表(list)/字典(dict)等对象在经过不断的数据赋值而没有进行手动回收,或者某些对象被不停的循环引用而不能及时的进行回收等都会产生内存泄露的情况。

一般在python代码块的调试过程中会使用memory-profiler、filprofiler、objgraph等三种方式进行辅助分析,今天这里主要介绍使用objgraph对象提供的函数接口来进行内存泄露的分析。

objgraph是python的非标准模块,因此需要使用pip的方式安装一下。

pip install objgraph

更多详细的介绍可以访问下面的官方地址进行查看。

https://mg.pov.lt/objgraph/

接下来就可以直接将objgraph导入到我们的代码块中进行使用了。

# Importing the objgraph module and renaming it to graph.

import objgraph as graph

这里初始化一组字典类型的数据对象。

dict_ = {

'姓名': ['Python', 'Java', 'Scala'],

'年龄': ['21', '22', '19']

}

通过objgraph.count()函数,可以统计出GC中的dict_对象的数目是多少。

# Counting the number of dict_ objects in the GC.

print(graph.count(dict_))

和objgraph.count()函数对应的是可以使用by_type返回该对象在GC中的列表,若是GC返回的为空的列表说明已经被回收了。

# Returning a list of dict_ objects in the GC.

print(graph.by_type(dict_))

在统计内存泄露时比较好用的函数就是graph.show_growth()函数,可以统计自上次调用以来增加得最多的对象。

# Showing the growth of objects in the memory since the last time it was called.

print(graph.show_growth())

# function 3013 +3013

# tuple 1463 +1463

# dict 1417 +1417

# wrapper_descriptor 1178 +1178

# ReferenceType 883 +883

# method_descriptor 814 +814

# builtin_function_or_method 794 +794

# getset_descriptor 514 +514

# type 463 +463

# list 436 +436

# None

可以根据返回结果中的对象每次增加的数量来判断内存泄露的相关情况。

还有一个比较常用的分析函数就是graph.show_most_common_types(),可以按照从大到小的方式列出对象实例比较多的情况。

# Showing the most common types of objects in the memory.

print(graph.show_most_common_types())

# function 3013

# tuple 1463

# dict 1417

# wrapper_descriptor 1178

# ReferenceType 883

# method_descriptor 814

# builtin_function_or_method 794

# getset_descriptor 514

# type 463

# list 436

# None

最后一个比较使用函数就是show_backrefs函数,使用它可以分析出内存泄露的原因是什么。

它会生成一张有关objs的引用图,可以看出对象为什么不释放?只是调用该函数时的参数比较多,下面是该函数的接口。

# def show_backrefs(objs, max_depth=3, extra_ignore=(), filter=None, too_many=10,

# highlight=None, filename=None, extra_info=None,

# refcounts=False, shortnames=True, output=None,

# extra_node_attrs=None):

我们还是和上面一样使用dict_作为对象进行分析。

# Showing the back references of the dict_ object.

graph.show_backrefs(dict_)

执行完成后dot类型的图片已经生成了,发现出现了下面的错误,意思是没有发现支持dot的图像组件。

# Graph written to C:\Users\86159\AppData\Local\Temp\objgraph-dkqm85f0.dot (4 nodes)

# Graph viewer (xdot) and image renderer (dot) not found, not doing anything else

可以使用pip的方式分别安装graphviz xdot,这两个python的非标准模块。

pip install graphviz xdot

若是查看.dot决策树图像可以使用graphviz工具,可以到下面地址进行下载安装。

https://graphviz.org/download/

安装完成后配置环境变量,然后重启开发工具(这里使用的是pycharm)即可。

到此这篇关于Python实现内存泄露排查的示例详解的文章就介绍到这了www.linuxprobe.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python3中的内存泄露是指程序在运行过程中,由于不正确的内存管理或者错误的使用方式,导致部分内存无法被释放而造成内存的持续增长。 Python3内存泄露的主要原因有以下几点: 1. 引用循环:当两个或多个对象彼此引用时,即使它们不再被使用,解释器无法对其进行垃圾回收,导致内存泄露。可以通过使用弱引用来解决这个问题。 2. 全局变量:全局变量会一直存在于整个程序的生命周期中,如果不及时释放或者不再使用时没有删除,就会造成内存泄露。 3. 未关闭的资源:例如打开文件、数据库连接或网络连接,如果不及时关闭这些资源,会导致内存泄露。 4. 大对象的创建和销毁:如果频繁创建和销毁大对象(如大型数据集),由于对象的内存无法及时释放,会导致内存泄露。 解决Python3内存泄露的方法如下: 1. 使用垃圾回收机制:Python3内置了垃圾回收机制,可以手动调用gc.collect()函数触发垃圾回收。可以通过合理使用gc模块中的弱引用、引用计数等方法来避免内存泄露。 2. 及时关闭资源:在使用完文件、数据库或网络连接后,及时调用相应的关闭方法,确保资源被正确释放。 3. 减少全局变量的使用:避免过多的使用全局变量,使用局部变量能够更及时地释放内存。 4. 使用生成器和迭代器:尽量使用生成器和迭代器来处理大量数据,可以减少大对象的创建和销毁,从而避免内存泄露。 总之,要避免Python3的内存泄露问题,需要合理管理内存资源,释放不再使用的对象,并重视垃圾回收机制的运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值