meliae内存分析-基本用法

2014年2月24日 12:58

python的内存分析工具meliae,挺好用的.
示例

1.记录程序的内存使用信息

import time

# 此处是可能发生内存泄露的地方
def main():
    pass

if __name__ == '__main__':
    # 通过循环执行,将泄露的内存积累放大
    while True:
        main()
        time.sleep(10)
        # 记录每次执行完后占用的内存
        from meliae import scanner
        scanner.dump_all_objects('mem_dump%s' % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

2.查看占用的内存大小

from meliae import loader
om = loader.load('mem_dump2014-02-2022-34-43')
om.summarize()
具体分析引用关系太麻烦,以上是个人喜欢的方法:
用循环将泄露的内存累积放大. 然后记录每次执行完后占用的内存.
查看占用内存大小. 再比较每次的内存大小,即可知道是否发生泄露.
至于内存泄露的地方,则用排除法,重复上述过程,定位泄露地点.
 
基本用法
  • 获取进程的内存信息
import time
from meliae import scanner
scanner.dump_all_objects('mem_dump%s' % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
  • 查看占用内存
from meliae import loader
#加载dump文件
om = loader.load('mem_dump2014-02-2022-34-43')
#分析内存占用情况
om.summarize()
  • 输出样例
Total 40335 objects, 125 types, Total size = 6.5MiB (6768944 bytes)
 Index   Count   %      Size   % Cum     Max Kind
     0    1245   3   1792824  26  26   98584 dict
     1   18560  46   1568824  23  49   12479 str
     2     226   0    730272  10  60   12624 module
     3     559   1    505336   7  67     904 type
     4    3573   8    457344   6  74     128 code
     5    3759   9    451080   6  81     120 function
     6    2506   6    189840   2  84     576 tuple
     7    1383   3    163768   2  86    4280 list
     8    1303   3    104240   1  88      80 wrapper_descriptor
     9     895   2     78760   1  89      88 weakref
    10     942   2     67824   1  90      72 builtin_function_or_method
    11     198   0     66928   0  91    8424 set
    12     388   0     65136   0  92    1552 unicode
    13     807   2     58104   0  93      72 method_descriptor
    14      50   0     56000   0  93    1120 OracleDB
    15    1680   4     40320   0  94      24 int
    16      36   0     36768   0  95    1192 StgDict
    17     446   1     32112   0  95      72 getset_descriptor
    18      87   0     29928   0  95     344 WeakSet
    19     395   0     28440   0  96      72 member_descriptor
 
字段说明
Index : 行索引号
Count : 该类型的对象总数
%(Count) : 该类型的对象总数 占 所有类型的对象总数 的百分比
Size : 该类型的对象总字节数
%(Size) : 该类型的对象总字节数 占 所有类型的对象总字节数 的百分比
Cum : 累积行索引后的%(Size)
Max : 该类型的对象中,最大者的字节数
Kind : 类型
 
  • 对象及引用关系
个人不喜欢用这个
#得到所有的OracleDB对象
p = om.get_all('OracleDB')
#查看第一个对象
p[0]
#可以查看该对象的所有引用
p[0].c
#查看谁引用了这个对象
p[0].p
 

Tags: 内存;meliae
评论(1) 阅读(5622)

理解select模块--等待IO完成

2014年1月26日 17:24

Tags: 非阻塞 python
评论(4) 阅读(2566)

socket.error: [Errno 32] Broken pipe错误的原因

2014年1月26日 15:47

linux下的socket程序,尝试发送消息到已关闭的socket上,会出现此错误.
 
示例代码
服务端server.py
#encoding=utf-8
import socket
import time


def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('0.0.0.0', 8050))
    sock.listen(5)

    client_sock, address = sock.accept()
    while True:
        msg = client_sock.recv(1024)
        print msg
        client_sock.send('from server: %s' % msg)
        time.sleep(1)
    client_sock.close()
    sock.close()


if __name__ == '__main__':
    main()
 
客户端client.py
#encoding=utf-8
import socket
import time


def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('0.0.0.0', 8050))
    while True:
        sock.send('hi')
        print sock.recv(1024)
        time.sleep(1)
    sock.close()


if __name__ == '__main__':
    main()
 
运行server.py和client.py,然后中断client.py会出现上面错误。

Tags: socket
评论(14) 阅读(16911)

objgraph无法生成分析图的原因

2014年1月14日 13:23

objgraph 是用于诊断内存问题的有用的工具 

安装objgraph

 

sudo pip install objgraph

用小段测试代码,生成png格式的分析图片

#encoding=utf-8
import objgraph


def main(hi):
    print hi

if __name__ == '__main__':
    hi = 'hi'
    main(hi)
    objgraph.show_backrefs([hi], filename='/tmp/hi.png')

会出现错误

Graph written to /tmp/objgraph-Nieb4E.dot (6 nodes)
Graph viewer (xdot) and image renderer (dot) not found, not doing anyt
hing else   

原因: 缺少依赖包

sudo yum install python-xdot  perl-Image-Dot

 

 

 

 

评论(12) 阅读(8488)

计算上月并且返回格式为xx

2014年1月07日 16:31

要求计算上月,并且返回格式为XX的

now = datetime.datetime.now()
last = now - datetime.timedelta(days=now.day)
print last.strftime('%m')

计算下个月

import calendar
import datetime

now = datetime.datetime.now()
max_days = calendar.monthrange(now.year, now.month)[1]
next = now + datetime.timedelta(days=max_days - now.day + 1)
print next.strftime('%m')

评论(1) 阅读(1560)

libpq-fe.h:没有那个文件或目录

2014年1月03日 09:13

安装psycopg2出现这个错误,需要安装postgresql-devel

sudo yum install postgresql-devel

评论(6) 阅读(4333)

Python.h:没有那个文件或目录

2014年1月03日 09:09

安装包出现上面错误,是因为缺少python-devel

sudo yum install python-devel

评论(0) 阅读(1542)

SimpleHttpServer出现unicodeDecodeError

2013年12月30日 09:46

在win8系统下运行 python -m SimpleHTTPServer 出现Traceback (most recent call last):

  File "D:\Python27\lib\runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "D:\Python27\lib\runpy.py", line 72, in _run_code
    exec code in run_globals
  File "D:\Python27\lib\SimpleHTTPServer.py", line 27, in <module>
    class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
  File "D:\Python27\lib\SimpleHTTPServer.py", line 208, in SimpleHTTPRequestHand
ler
    mimetypes.init() # try to read system mime.types
  File "D:\Python27\lib\mimetypes.py", line 358, in init
    db.read_windows_registry()
  File "D:\Python27\lib\mimetypes.py", line 258, in read_windows_registry
    for subkeyname in enum_types(hkcr):
  File "D:\Python27\lib\mimetypes.py", line 249, in enum_types
    ctype = ctype.encode(default_encoding) # omit in 3.x!
UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal
not in range(128)

在import SimpleHTTPServer时,同样出现上面的错误.

在import sys后面加上下面语句

reload(sys)
sys.setdefaultencoding('gbk')

评论(3) 阅读(2618)

with让数据库操作代码变得清爽

2013年12月17日 21:03

对数据操通常都需要打开与关闭连接,而且用try-finally保证连接被关闭.

这些常规的操作会让代码变得难看.

db = web.database(dbn='oracle', db='......', user='hy', pw='1234')
try:
    db.query("select * from t_c_ms_interface")
finally:
    db.ctx.db.close()

用上下文协议隐藏这些操作

class IPCCCDB:
    def __init__(self):
        self.dns = '....'

    def __enter__(self):
        import web
        self.db = web.database(dbn='oracle', db=self.dns, user='hy', pw='1234')
        return self.db

    def __exit__(self, type, value, traceback):
        self.db.ctx.db.close()

然后,变得如此清爽

with IPCCCDB() as db:
    db.query("select * from t_c_ms_interface")

评论(7) 阅读(2280)

python排列*号

2013年12月10日 11:24

输出以下内容

*
***
*****
*******
*********
***********
     *
    ***
   *****
  *******
 *********
***********   
 
借用str的format可以方便的实现,但只有python2.6以上才支持
f = '{:<11}'
print '\n'.join([f.format('*' * i) for i in range(1, 12, 2)])
f = '{:^11}'
print '\n'.join([f.format('*' * i) for i in range(1, 12, 2)])
 

Tags: 字符串
评论(4) 阅读(1682)