pytracemalloc安装与使用

pytracemalloc用于跟踪Python内存的分配情况,在我们的项目中用于在后期优化性能使用。

1.安装

pytracemalloc的安装需要修改Python的源码,我们创建一个名为pytracemalloc的目录,进入目录,运行如下命令:

> wget http://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
> wget https://pypi.python.org/packages/source/p/pytracemalloc/pytracemalloc-1.2.tar.gz
> tar -xf Python-2.7.8.tgz
> tar -xf pytracemalloc-1.2.tar.gz
> cd Python-2.7.8
> patch -p1 < ../pytracemalloc-1.2/patches/2.7/pep445.patch
> ./configure --prefix=../build/
> make && make install
> cd ../pytracemalloc-1.2
> ../bin/python setup.py install

2.简单的实例

显示最占用内存的10行代码

1 # -*- coding:utf-8 -*-
  2
  3 import os
  4 import sys
  5 import tracemalloc
  6
  7 tracemalloc.start()
  8
  9 li = []
10 for i in xrange(0, 100000):
11     li.append(i)
12
13 class A(object):
14     def __init__(self):
15         self.m = {}
16         for i in xrange(0, 10):
17             self.m[i] = i * i
18
19 obj_li = []
20 for i in xrange(0, 100000):
21     obj_li.append(A())
22
23 snapshot = tracemalloc.take_snapshot()
24 top_stats = snapshot.statistics("lineno")
25
26 for line in top_stats[:10]:
27     print line

运行结果如下:

test.py:17: size=73.0 MiB, count=100000, average=768 B
test.py:15: size=53.0 MiB, count=199999, average=280 B
test.py:21: size=7055 KiB, count=100004, average=72 B
test.py:10: size=2356 KiB, count=2432, average=992 B
test.py:11: size=805 KiB, count=1, average=805 KiB
test.py:13: size=1952 B, count=7, average=278 B
test.py:23: size=456 B, count=1, average=456 B
test.py:14: size=120 B, count=1, average=120 B
test.py:16: size=72 B, count=1, average=72 B

比较两个snapshot的不同

1 # -*- coding:utf-8 -*-
  2
  3 import os
  4 import sys
  5 import tracemalloc
  6
  7 tracemalloc.start()
  8
  9 li = []
10 for i in xrange(0, 100000):
11     li.append(i)
12
13 class A(object):
14     def __init__(self):
15         self.m = {}
16         for i in xrange(0, 10):
17             self.m[i] = i * i
18
19 obj_li = []
20 for i in xrange(0, 100000):
21     obj_li.append(A())
22
23 snapshot1 = tracemalloc.take_snapshot()
24
25 for i in xrange(0, 1000):
26     obj_li.append(A())
27
28 snapshot2 = tracemalloc.take_snapshot()
29
30 top_stats = snapshot2.compare_to(snapshot1, "lineno")
31
32 for line in top_stats[:10]:
33     print line

下面是输出结果:

test.py:17: size=73.0 MiB (+750 KiB), count=101000 (+1000), average=768 B
test.py:15: size=53.0 MiB (+546 KiB), count=201999 (+2000), average=280 B
test.py:26: size=62.0 KiB (+62.0 KiB), count=1000 (+1000), average=64 B
/Users/whosemario/MyApplications/pytracemalloc/build/lib/python2.7/site-packages/tracemalloc.py:380: size=1008 B (+1008 B), count=6 (+6), average=168 B
/Users/whosemario/MyApplications/pytracemalloc/build/lib/python2.7/site-packages/tracemalloc.py:518: size=672 B (+672 B), count=4 (+4), average=168 B
/Users/whosemario/MyApplications/pytracemalloc/build/lib/python2.7/site-packages/tracemalloc.py:308: size=280 B (+280 B), count=1 (+1), average=280 B
/Users/whosemario/MyApplications/pytracemalloc/build/lib/python2.7/site-packages/tracemalloc.py:306: size=64 B (+64 B), count=1 (+1), average=64 B
test.py:21: size=7055 KiB (+0 B), count=100004 (+0), average=72 B
test.py:10: size=2356 KiB (+0 B), count=2432 (+0), average=992 B
test.py:11: size=805 KiB (+0 B), count=1 (+0), average=805 KiB

果然python的dict是很耗内存的,这让我想到了原来的项目的优化。

3.Reference

  1. pytracemalloc官网 - http://pytracemalloc.readthedocs.org/index.html#