python 內存分析 流程圖


memory_profiler 模塊被用於在逐行的基礎上,測量你代碼的內存使用率,也建議安裝 psutil 包,使得 memory_profile 模塊運行的更快

from memory_profiler import profile
 
 
@profile(precision=6)
def primes(n):
    if n == 2:
        return [2]
    elif n < 2:
        return []
    s = range(3, n + 1, 2)
    mroot = n ** 0.5
    half = (n + 1) / 2 - 1
    i = 0
    m = 3
    while m <= mroot:
        if s[i]:
            j = (m * m - 3) / 2
            s[j] = 0
            while j < half:
                s[j] = 0
                j += m
        i = i + 1
        m = 2 * i + 3
    return [2] + [x for x in s if x]
 
 
len(primes(100000))

 

meliae會把某個時刻的內存給dump到一個文件中,然后再對該文件進行分析,當我們的某個python程序占用內存很大,可能有內存泄露發生時,可以使用該工具來進行檢測分析

 

Guppy (使用了Heapy):使用 guppy 包,你可以跟蹤每個類型在你代碼中每個階段(字符, 元組, 字典 等等)有多少對象被創建了,查看占用內存前十位變量的工具

 

objgraph模塊:該工具允許你查看內存中對象的數量,定位含有該對象的引用的所有代碼的位置。

.定位哪個對象引起內存泄漏
# -*- coding: utf-8 -*-
import objgraph

_cache = []

class OBJ(object):
    pass

def func_to_leak():
    o = OBJ()
    _cache.append(o)
    # do something with o, then remove it from _cache 
 
    if True: # this seem ugly, but it always exists
       return 
       
    _cache.remove(o)
 
if __name__ == '__main__':
   objgraph.show_growth()
    try:
       func_to_leak()
    except:
       pass
    print '********after call func_to_leak*********'
   objgraph.show_growth()
    
運行結果(我們只關心后一次 show_growth 的結果)如下

wrapper_descriptor           1196    +1196
function                   1187    +1187
builtin_function_or_method     739     +739
method_descriptor            635     +635
dict                        539     +539
weakref                     457     +457
tuple                       364     +364
getset_descriptor            306     +306
list                        232     +232
member_descriptor            227     +227
********after call func_to_leak*********
wrapper_descriptor    1205       +9
getset_descriptor      310       +4
member_descriptor      230       +3
weakref              459       +2
dict                 541       +2
OBJ                   1      +1  

從運行結果可以發現,調用函數之后,增加了一個類 OBJ 的實例,然而理論上函數調用結束之后,所有在函數作用域(local)中聲明的對象都改被銷毀,因此這里就存在內存泄露。
  • 顯示占據python程序內存的頭N個對象
  • 顯示一段時間以后哪些對象被刪除活增加了
  • 在我們的腳本中顯示某個給定對象的所有引用
 

 

============快速生成陌生代碼的函數調用關系

1、graphviz(Graph Visualization Software-圖形可視化軟件)

2、pycallgraph(創建python的可視化圖形)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM