本文主要介绍3个工具:pdb,objgraph,以及pympler。
1.pdb
pdb是专门用于python代码调试,模仿gdb。 使用pdb可以查看堆栈,打印变量等。
这里介绍的是命令行下的pdb。 命令行下使用pdb,代码侵入小,调试方便。
本例中,python安装在当前目录下.venv
使用pdb加载python程序
.venv/bin/python -m pdb orange.py > /Users/lanyang/workspace/orange/orange.py(3)<module>() -> import inspect (Pdb)
启动程序
(Pdb)c
这样,python代码就开始执行了。
相关的命令有
bt 打印堆栈 q 退出 pp 打印变量 c(ont(inue)) 继续执行更多命令可参考:
(Pdb) help Documented commands (type help <topic>): ======================================== EOF c d h list q rv undisplay a cl debug help ll quit s unt alias clear disable ignore longlist r source until args commands display interact n restart step up b condition down j next return tbreak w break cont enable jump p retval u whatis bt continue exit l pp run unalias where Miscellaneous help topics: ========================== exec pdb
objgraph
安装objgraph
pip install objgraph
查看最常用的类型
(Pdb) import objgraph (Pdb) objgraph.show_most_common_types(limit=20) function 22750 dict 15520 tuple 12536 weakref 6679 list 5516 type 3449 getset_descriptor 3408 cell 2566 set 2496 ModuleSpec 1588 module 1582 SourceFileLoader 1502 wrapper_descriptor 1332 builtin_function_or_method 1241 method_descriptor 1219 property 1171 member_descriptor 822 classmethod 697 WeakSet 571 MovedAttribute 501
感觉这个函数没什么用。
查看增长最快的类型
(Pdb) objgraph.show_growth(limit=10) function 22749 +22749 dict 15515 +15515 tuple 12332 +12332 weakref 6680 +6680 list 5517 +5517 type 3449 +3449 getset_descriptor 3408 +3408 cell 2565 +2565 set 2496 +2496 ModuleSpec 1588 +1588
show_growth() 打印两次调用之间增加的类型。如果这其中有自己定义的类型,很可能就是问题所在。如果都是python内置类型,可能要花费更多功夫了。
一般排查问题时,在程序开始执行时,调用 show_growth() ,程序跑一段时间后,再次调用 show_growth() ,查看哪些对象增长最快。
如果使用pdb在命令行下调试,ctrl+c停止程序的时候,注意观察上下文,保证跟上次 import objgraph 时一样,否则,会出现:
(Pdb) objgraph.show_growth(limit=10) *** NameError: name 'objgraph' is not defined (Pdb)
如果出现这个问题,可以继续让程序执行,再ctrl+c停止程序。
查看某个类型
(Pdb) objgraph.by_type('list')
这个可能会打印一堆。
pympler
使用objgraph时,虽然可以看到增长最快的对象,但是无法得知占用内存最多的是哪个。
下面我们就使用pympler,查看内存占用。
(Pdb) from pympler import tracker (Pdb) tr = tracker.SummaryTracker() (Pdb) tr.print_diff() types | # objects | total size ======================= | =========== | ============ <class 'list | 12769 | 1.18 MB <class 'str | 12769 | 950.47 KB <class 'int | 2513 | 68.71 KB <class 'code | 1 | 144 B function (store_info) | 1 | 136 B <class 'cell | 2 | 96 B <class 'tuple | 1 | 64 B <class 'method | -1 | -64 B <class 'dict | 0 | -128 B (Pdb) tr.print_diff() types | # objects | total size ============== | =========== | ============ <class 'list | 1 | 88 B <class 'str | 1 | 70 B (Pdb) tr.print_diff() types | # objects | total size ======= | =========== | ============ (Pdb)
参考
pdb
objgraph
pympler
Python内存泄露调试指导思想
使用gc、objgraph干掉python内存泄露与循环引用!
python 进程内存增长问题, 解决方法和工具
查看更多关于排查python内存泄露中几个工具的使用的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did171703