追踪代码申请的内存大小
追踪代码申请的内存大小
tracemalloc
为python代码{%code%}添加如下代码:
1 | import tracemalloc |
追踪这片代码所涉及的内存申请过程,包括所申请内存的大小
对记录结果进行分析:
1 | from collections import defaultdict |
可以查看自己所写的代码所申请内存空间大小的变化情况
memory_profiler
1 | import numpy as np |
结果:
1 | Line # Mem usage Increment Occurrences Line Contents |
objgraph+gc
1 | # -*- coding: utf-8 -*- |
结果
1 | gc: collectable <tuple 0x00000160C3B46020> |
在gdb输入处键入
1 | (Pdb) import objgraph |
得到描述对象之间关系(引用链)的图像
objgraph.show_growth
通过两次objgraph.show_growth()的调用环境差异得到内存中增加的对象。
1 | # -*- coding: utf-8 -*- |
结果
1 | function 2884 +2884 |
在调用完func_to_leak()之后,内存中还存在着OBJ实例
objgraph.show_most_common_types给出程序上下文中占用内存的数量较多的变量类型,默认给出最多的前十种
1 | # -*- coding: utf-8 -*- |
输出结果
1 | function 2884 |
注释掉gc.disable语句,输出结果(30种最多的变量类型)
1 | function 2884 |
可以看到,有一半的OBJ实例没有被回收,存在内存泄漏
pympler
1 | from pympler import tracker,muppy,summary |
打印结果
1 | memory total |
监测内存中变量类型的变化
guppy
安装pip install guppy3
1 | from guppy import hpy |
打印结果
1 | Partition of a set of 2022181 objects. Total size = 267902754 bytes. |
结果比较粗糙,只能看到numpy.ndarray类型变量所占内存空间有增有减,其他类型变量所占内存空间没有变化,没什么参考意义,不好用
对打印结果进行统计,代码如下,提取关键打印内容和画图的代码跟下一节的结果分析代码相同
1 | import json |
mem_top
安装pip install mem_top
1 | from mem_top import mem_top |
打印结果
1 |
|
mem_top里参数limit控制显示最高占用量的对象,refs是指包含最多引用的对象,bytes是指占用内存空间最多的对象,types是指数量最多的对象类型。代码实现细节参见denis-ryzhkov/mem_top。间隔一段时间长时间观测,就能发现端倪。python进程内存占用持续增高排查经验分享,mem_top统计整个进程的内存占用情况,只要程序A的代码不变且mem_top被包含在程序A的代码里,无论mem_top插在哪里都是相同的结果。
附上mem_top结果的分析代码,以观察什么因素在增高导致内存泄露
1 | # 1. 提取要分析的关键内容 |
memprof
1 | from memprof import * |
代码运行目录下会生成func.log和func.png(描述func中的占用内存空间超过1MB的变量的内存使用量随着时间的变化情况)
参考链接:
使用gc、objgraph干掉python内存泄露与循环引用!
创建于202411052157,修改于202412012056