程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Memory usage for Python performance analysis

編輯:Python

This is my participation 2022 For the first time, the third challenge is 29 God , Check out the activity details 2022 For the first time, it's a challenge

In the last article, we learned how to view the time consumption in code , Today we continue to talk about memory consumption in programs , Of course for python We also have ready-made bags Fabian Pedregosa With Robert Kern Of line_profiler For the model , Achieved a good Memory Analyzer .

First : adopt pip install :

$ pip install -U memory_profiler
$ pip install psutil
 Copy code 

( It is recommended to install psutil package , Because it greatly improves memory_profiler Performance of ).

And line_profiler equally ,memory_profiler You are required to decorate the functions you are interested in with the following decorators @profile

@profile
def primes(n):
...
...
 Copy code 

To see how much memory your function uses , Please run the following command :

$ python -m memory_profiler primes.py
 Copy code 

Once the program exits , You should see the output shown below :

Filename: primes.py
![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4ee8612d0ef54825ad8458b6ee30ea38~tplv-k3u1fbpfcp-watermark.image?)
Line # Mem usage Increment Line Contents
==============================================
2 @profile
3 7.9219 MB 0.0000 MB def primes(n):
4 7.9219 MB 0.0000 MB if n==2:
5 return [2]
6 7.9219 MB 0.0000 MB elif n<2:
7 return []
8 7.9219 MB 0.0000 MB s=range(3,n+1,2)
9 7.9258 MB 0.0039 MB mroot = n ** 0.5
10 7.9258 MB 0.0000 MB half=(n+1)/2-1
11 7.9258 MB 0.0000 MB i=0
12 7.9258 MB 0.0000 MB m=3
13 7.9297 MB 0.0039 MB while m <= mroot:
14 7.9297 MB 0.0000 MB if s[i]:
15 7.9297 MB 0.0000 MB j=(m*m-3)/2
16 7.9258 MB -0.0039 MB s[j]=0
17 7.9297 MB 0.0039 MB while j<half:
18 7.9297 MB 0.0000 MB s[j]=0
19 7.9297 MB 0.0000 MB j+=m
20 7.9297 MB 0.0000 MB i=i+1
21 7.9297 MB 0.0000 MB m=2*i+3
22 7.9297 MB 0.0000 MB return [2]+[x for x in s if x]
 Copy code 

line_profiler and memory_profiler Of IPython Shortcut

Of course line_profiler,memory_profiler Both of these programs are from IPython Shortcuts accessed in , As shown below , This can save a lot of time and energy , You can analyze the code without modifying any source code

%load_ext memory_profiler
%load_ext line_profiler
 Copy code 

Where is the memory leak ?

cPython The interpreter uses reference counting as the main method of tracking memory . This means that each object contains a counter , This counter is incremented when the reference to the object is stored somewhere , And decrement when deleting the reference to the object . When the counter reaches zero ,cPython The interpreter knows that the object is no longer used , So it deletes the object and frees up the occupied memory .

If even the object is no longer used , References to objects still exist , Memory leaks often occur in programs .

Find these “ Memory leak ” The quickest way to use is by Marius Gedminas It's called objgraph Excellent tools . This tool allows you to view the number of objects in memory , And locate all the different locations in the code that hold references to these objects .

To start , First installation objgraph

pip install objgraph
 Copy code 

After installing this tool , Insert a statement into the code to call the debugger :

import pdb; pdb.set_trace()
 Copy code 
Which objects are most common ?

At run time , You can check the most popular program by running the following command 20 Objects :

(pdb) import objgraph
(pdb) objgraph.show_most_common_types()
MyBigFatObject 20000
tuple 16938
function 4310
dict 2790
wrapper_descriptor 1181
builtin_function_or_method 934
weakref 764
list 634
method_descriptor 507
getset_descriptor 451
type 439
 Copy code 
Which objects have been added or deleted ?

We can also see which objects are added or deleted between two points in time :

(pdb) import objgraph
(pdb) objgraph.show_growth()
.
.
.
(pdb) objgraph.show_growth() # this only shows objects that has been added or deleted since last show_growth() call
traceback 4 +2
KeyboardInterrupt 1 +1
frame 24 +1
list 667 +1
tuple 16969 +1
 Copy code 
What is referencing this leaked object ?

Continue along this route , We can also see where references to any given object are stored . Let's take the following simple program as an example :

x = [1]
y = [x, [x], {"a":x}]
import pdb; pdb.set_trace()
 Copy code 

To see what holds a reference to a variable x, Please run the following objgraph.show_backref() function :

(pdb) import objgraph
(pdb) objgraph.show_backref([x], filename="/tmp/backrefs.png")
 Copy code 

The output of this command should be stored in PNG Images /tmp/backrefs.png, It should look like this :

The box with red font at the bottom is the object we are interested in . We can see that it is referenced by symbols x once , Referenced by the list y Three times . If x Is the object that caused the memory leak , We can use this method to see why it is not automatically released by tracking all its references .


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved