zoukankan      html  css  js  c++  java
  • 排查python内存泄露中几个工具的使用

    本文主要介绍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)
    1
    2
    3
    4
    启动程序

    (Pdb)c
    1
    这样,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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    2.objgraph
    安装objgraph

    pip install objgraph
    1
    查看最常用的类型

    (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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    感觉这个函数没什么用。

    查看增长最快的类型

    (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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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)
    1
    2
    3
    如果出现这个问题,可以继续让程序执行,再ctrl+c停止程序。

    查看某个类型

    (Pdb) objgraph.by_type('list')
    1
    这个可能会打印一堆。

    3.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)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    tracker对象初始化的时候会创建一个summary,每次调用tracker.print_diff()的时候又会创建一个summary,当前的summary与上次的summary做比较,并打印两者之间的不同。

    4.参考
    pdb

    objgraph

    pympler

    pympler muppy

    Python内存泄露调试指导思想

    使用gc、objgraph干掉python内存泄露与循环引用!

    python 进程内存增长问题, 解决方法和工具
    ————————————————
    版权声明:本文为CSDN博主「翔云123456」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/lanyang123456/java/article/details/100860904

  • 相关阅读:
    gc buffer busy/gcs log flush sync与log file sync
    给Oracle年轻的初学者的几点建议
    Android 编程下帧动画在 Activity 启动时自动运行的几种方式
    Android 编程下 Touch 事件的分发和消费机制
    Java 编程下 static 关键字
    Java 编程下 final 关键字
    Android 编程下模拟 HOME 键效果
    Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
    Extjs4 大型项目目录结构重构
    [转]SQLServer 2008 允许远程连接的配置方法
  • 原文地址:https://www.cnblogs.com/ExMan/p/12891475.html
Copyright © 2011-2022 走看看