找回密码
 会员注册
查看: 42|回复: 0

Python内存泄漏排查

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71769
发表于 2024-9-6 20:09:01 | 显示全部楼层 |阅读模式
Python内存泄漏排查1.排查工具1.1gc1.2tracemalloc1.3mem_top1.4guppy1.5objgraph1.6pympler1.7pyrasite2.案例分析3.参考记一次排查Python程序内存泄漏的问题。1.排查工具工具说明gcPython标准库内置模块tracemalloc推荐Python3.4以上此工具为标准库mem_top推荐是对gc的封装,能够排序输出最多的TopN,执行快guppy可以对堆里边的对象进行统计,算是比较实用;但计算耗时长objgraph可以绘制对象引用图,对于对象种类较少,结构比较简单的程序适用pympler可以统计内存里边各种类型的使用,获取对象的大小pyrasite非常强大的第三方库,可以渗透进入正在运行的python进程动态修改里边的数据和代码各个工具官网文档都有详细说明,也有基本示例用法,本文简单介绍工具的常见使用。1.1gcgc作为内置模块,Python2和Python3都支持,用起来非常方便。常用的方法有:gc.collect(generation=2)若被调用时不包含参数,则启动完全的垃圾回收;在排查内存泄漏时,为避免垃圾未及时回收的影响,在统计前可以先手动调用一下垃圾回收;gc.get_objects()返回一个收集器所跟踪的所有对象列表;gc.get_referrers(*objs)返回直接引用任意一个objs的对象列表。这个函数只定位支持垃圾回收的容器;引用了其它对象但不支持垃圾回收的扩展类型不会被找到。gc.get_referents(*ojbs)返回被任意一个参数中的对象直接引用的对象的列表,在排查内存泄漏中一般需要排查被引用的对象列表;sys.getsizeof(obj)返回对象的大小(以字节为单位),只计算直接分配给对象的内存消耗,不计算它所引用的对象的内存消耗。示例用法:importgc,sysdeftop_memory(limit=3):gc.collect()objs_by_size=[]forobjingc.get_objects():size=sys.getsizeof(obj)objs_by_size.append((obj,size))#按照内存分配大小排序sorted_objs=sorted(objs_by_size,key=lambdax:x[1],reverse=True)forobj,sizeinsorted_objs[:limit]:print(f"size:{size/1024/1024:.2f}MB,type:{type(obj)},obj:{id(obj)}")#输出被引用列表foritemingc.get_referents(obj):print(f"{item}\n")1234567891011121314151.2tracemallocPython3.4以上的内置库。tracemalloc模块是一个用于对python已申请的内存块进行debug的工具。它能提供以下信息:回溯对象分配内存的位置按文件、按行统计python的内存块分配情况:总大小、块的数量以及块平均大小对比两个内存快照的差异,以便排查内存泄漏常用函数介绍:tracemalloc.start()可以在运行时调用函数来启动追踪Python内存分配tracemalloc.take_snapshot()保存一个由Python分配的内存块的追踪的快照。返回一个新的Snapshot实例Snapshot.compare_to计算与某个旧快照的差异代码示例:importtracemalloctracemalloc.start()#...startyourapplication...snapshot1=tracemalloc.take_snapshot()#...callthefunctionleakingmemory...snapshot2=tracemalloc.take_snapshot()top_stats=snapshot2.compare_to(snapshot1,'lineno')print("[Top10differences]")forstatintop_stats[:10]:print(stat)12345678910111213官网有非常详细的说明文档和使用示例,详见1.3mem_topmem_top其实是对gc模块的方法的封装,调用mem_top.mem_top()函数能够直接打印出按照被引用数量、占用内存大小、按照类型统计对象个数三种方式排序的topN信息。安装pipinstallmem-top函数说明:mem_top(limit=10,#limitoftoplinespersectionwidth=100,#widthofeachlineincharssep='\n',#chartoseparatelineswithrefs_format='{num}\t{type}{obj}',#formatoflinein"refs"sectionbytes_format='{num}\t{obj}',#formatoflinein"bytes"sectiontypes_format='{num}\t{obj}',#formatoflinein"types"sectionverbose_types=None,#listoftypestosortvaluesby`repr`lengthverbose_file_name='/tmp/mem_top',#nameoffiletostoreverbosevaluesin)12345678910示例mem_top.mem_top(limit=3,width=200)输出:refs:1638 {'IPython.core.error':,'ipython_genutils.py3compat':[u'd={\n"@babel/core":"^7.24.4",\n"@babel/plugin-proposal-class-properties":"^7.18.6",\n"@babel/preset-env":"^7.9.5",\n"@jest/globals":"^29.7.0",\n"babel-eslint":"^10.1.0",\765 [u'd={\n"@babel/core":"^7.24.4",\n"@babel/plugin-proposal-class-properties":"^7.18.6",\n"@babel/preset-env":"^7.9.5",\n"@jest/globals":"^29.7.0",\n"babel-eslint":"^10.1.0",\bytes:49432 {'IPython.core.error':,'ipython_genutils.py3compat':7527 6102 12345678910111213141.4guppygunppy是一个非常强大的工具,但同时缺点也比较明细,执行耗时不适合生产debug。安装pipinstallguppy注意该库会寻找使用对象的dir相关属性,注意若是自行实现的__dir__函数有问题,会导致该库初始化出现异常。常用示例:importdatetimeimportguppy#初始化了SessionContext,使用它可以访问heap信息analyzer=guppy.hpy()defdo_something():#runyourapp...print("==={}heaptotal===".format(datetime.datetime.now().strftime("%Y-%m-%d%H:%M:%S")))#返回heap内存详情heap=analyzer.heap()print(heap)#byvia返回该对象的被哪些引用,heap[0]是内存消耗最大的对象print("==={}references===".format(datetime.datetime.now().strftime("%Y-%m-%d%H:%M:%S")))references=heap[0].byviaprint(references)print("==={}referencesdetail===".format(datetime.datetime.now().strftime("%Y-%m-%d%H:%M:%S")))print(references[0].kind)#类型print(references[0].shpaths)#路径print(references[0].rp)#引用12345678910111213141516171819202122输出结果:===2024-07-2116:27:12heaptotal===Partitionofasetof785315objects.Totalsize=104732120bytes.IndexCount%Size%Cumulative%Kind(class/dictofclass)03963725035974232343597423234unicode123029323814136235978836857dict(noowner)21437991813556704137334507270str37547310737299278071806477tuple410850263468038335274480dictofmodule527640250038428585312882type6192062245836828831149684types.CodeType7158572240922429072072087list8194022232824029304896089function927640221584029526480091dictoftype===2024-07-2116:27:14references===Partitionofasetof396372objects.Totalsize=35974232bytes.IndexCount%Size%Cumulative%ReferredVia:01874851371888413718884'.keys()[0]'1130463974352323462407'.keys()[1]'299583724328230705689'.keys()[2]'3902726585762372914410'.keys()[3]'4863626322642436140812'.keys()[4]'5817526070322496844014'.keys()[5]'671505156881548412815'.func_doc','[0]'7655725028801598700817'.keys()[6]'8578514289041641591218'.keys()[7]'9516813924321680834419'.keys()[8]'===2024-07-2116:27:16referencesdetail===0:hpy().Root.i0_modules['kombu'].__dict__.keys()[0]ReferencePatternby.0:_---[-]18748:0x7ff3f82dec30,0x7ff3f82decc0...1:a[-]18753dict(noowner):0x7ff3f82f7050*24,0x7ff3f82f73b0*3...2:aa----[-]317dict(noowner):0x7ff3f88e43b0*1,0x7ff3f88e44d0*1...3:a3[-]77dictofaliyunsdkcore.endpoint.endpoint_resolver_rules.En...4:a4------[-]77aliyunsdkcore.endpoint.endpoint_resolver_rules.EndpointR...5:a5[-]77list:0x7ff3f88f65f0*6,0x7ff3f897e7d0*6...6:a6--------[-]77dictofaliyunsdkcore.endpoint.chained_endpoint_resolv...7:a7[+]77aliyunsdkcore.endpoint.chained_endpoint_resolver.Chai...8:aab----[-]80dict(noowner):0x7ff3f88e44d0*1,0x7ff3f88e8b90*1...9:aaba[-]78dictofaliyunsdkcore.retry.retry_condition.DefaultConfi...12345678910111213141516171819202122232425262728293031323334353637383940414243除了官网的文档,还可以通过类的属性查看相关说明:analyzer=guppy.hpy()heap=analyzer.heap()print("==============HeapDocuments====================")print(analyzer.doc)print("=============HeapStatusDocuments================")print(heap.doc)123456输出:==============HeapDocuments====================ToplevelinterfacetoHeapy.Availableattributes:AnythingNothingViaisoClassRcsdocloadClodoRootfindexmonitorIdSizeheappbIdsetTypeheapusetrefModuleUnityidsettestUseeg:hpy().doc.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 13:57 , Processed in 0.648871 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表