Python Object Graphs — objgraph 1.7.2 documentation

Python Object Graphs

objgraph is a module that lets you visually explore Python object graphs.

You’ll need graphviz if you want to draw the pretty graphs.

I recommend xdot for interactive use. pip install xdot should suffice; objgraph will automatically look for it in your PATH.

Installation and Documentation

pip install objgraph or download it from PyPI.

Documentation lives at http://mg.pov.lt/objgraph.

Quick start

Try this in a Python shell:

>>> x = []
>>> y = [x, [x], dict(x=x)]
>>> import objgraph
>>> objgraph.show_refs([y], filename='sample-graph.png')
Graph written to ....dot (... nodes)
Image generated as sample-graph.png

(If you’ve installed xdot, omit the filename argument to get the interactive viewer.)

You should see a graph like this:

Backreferences

Now try

>>> objgraph.show_backrefs([x], filename='sample-backref-graph.png')
...
Graph written to ....dot (8 nodes)
Image generated as sample-backref-graph.png

and you’ll see

Memory leak example

The original purpose of objgraph was to help me find memory leaks. The idea was to pick an object in memory that shouldn’t be there and then see what references are keeping it alive.

To get a quick overview of the objects in memory, use the imaginatively-named show_most_common_types():

>>> objgraph.show_most_common_types()
tuple 5224
function 1329
wrapper_descriptor 967
dict 790
builtin_function_or_method 658
method_descriptor 340
weakref 322
list 168
member_descriptor 167
type 163

But that’s looking for a small needle in a large haystack. Can we limit our haystack to objects that were created recently? Perhaps.

Let’s define a function that “leaks” memory

>>> class MyBigFatObject(object):
... pass
...
>>> def computate_something(_cache={}):
... _cache[42] = dict(foo=MyBigFatObject(),
... bar=MyBigFatObject())
... # a very explicit and easy-to-find "leak" but oh well
... x = MyBigFatObject() # this one doesn't leak

We take a snapshot of all the objects counts that are alive before we call our function

>>> objgraph.show_growth(limit=3)
tuple 5228 +5228
function 1330 +1330
wrapper_descriptor 967 +967

and see what changes after we call it

>>> computate_something()
>>> objgraph.show_growth()
MyBigFatObject 2 +2
dict 797 +1

It’s easy to see MyBigFatObject instances that appeared and were not freed. I can pick one of them at random and trace the reference chain back to one of the garbage collector’s roots.

For simplicity’s sake let’s assume all of the roots are modules; if you’ve any examples where that isn’t true, I’d love to hear about them (although see Reference counting bugs).

>>> import inspect, random
>>> objgraph.show_chain(
... objgraph.find_backref_chain(
... random.choice(objgraph.by_type('MyBigFatObject')),
... inspect.ismodule),
... filename='chain.png')
Graph written to ...dot (13 nodes)
Image generated as chain.png

It is perhaps surprising to find linecache at the end of that chain (apparently doctest monkey-patches it), but the important things – computate_something() and its cache dictionary – are in there.

There are other tools, perhaps better suited for memory leak hunting: heapy, Dozer.

Reference counting bugs

Bugs in C-level reference counting may leave objects in memory that do not have any other objects pointing at them. You can find these by calling get_leaking_objects(), but you’ll have to filter out legitimate GC roots from them, and there are a lot of those:

>>> roots = objgraph.get_leaking_objects()
>>> len(roots)
4621
>>> objgraph.show_most_common_types(objects=roots)
...
tuple 4333
dict 171
list 74
instancemethod 4
listiterator 2
MemoryError 1
Sub 1
RuntimeError 1
Param 1
Add 1
>>> objgraph.show_refs(roots[:3], refcounts=True, filename='roots.png')
...
Graph written to ...dot (19 nodes)
Image generated as roots.png

History

I’ve developed a set of functions that eventually became objgraph when I was hunting for memory leaks in a Python program. The whole story – with illustrated examples – is in this series of blog posts:

And here’s the change log

Support and Development

The source code can be found in this Bazaar repository: https://code.launchpad.net/~mgedmin/objgraph/trunk.

To check it out, use bzr branch lp:objgraph.

Report bugs at https://bugs.launchpad.net/objgraph.

For more information, see Hacking on objgraph.

Python Object Graphs — objgraph 1.7.2 documentation的更多相关文章

  1. Odoo8查询产品时提示"maximum recursion depth exceeded while calling a Python object"

    今天在生产系统中查询产品时,莫名提示错误:maximum recursion depth exceeded while calling a Python object,根据错误日志提示,发现在查询产品 ...

  2. scrapy RuntimeError: maximum recursion depth exceeded while calling a Python object 超出python最大递归数异常

    2019-10-21 19:01:00 [scrapy.core.engine] INFO: Spider opened2019-10-21 19:01:00 [scrapy.extensions.l ...

  3. pickle — Python object serialization

    pickle - Python object serialization  消息队列

  4. Python Object Oriented

    1. Creating class class className: 'Optional class documentation string' class_suite The class has a ...

  5. python object对象

    动态语言的对象属性 既然都是动态语言,自然python和熟知的JavaScript很像,建一个空对象用来存放所有的数据,看看js: var data = {}; data.name = 'CooMar ...

  6. [Python] Object spread operator in Python

    In JS, we have object spread opreator: const x = { a: '1', b: '2' } const y = { c: '3', d: '4' } con ...

  7. Commons JXPath - Modifying Object Graphs

    JXPath 除了可以 XPath 语法访问 JavaBeans.DOM/JDOM,也可以对其属性赋值. 以下面的 JavaBeans 为例. package com.huey.jxpath; imp ...

  8. python object takes no parameters

    class Song(object): def __init__(self,lyrics): self.lyrics = lyrics def sing_me_a_song(self): for li ...

  9. python object类

    这个应为写得,写得蛮啰嗦的,建议耐心的人看看:http://www.cafepy.com/article/python_types_and_objects/python_types_and_objec ...

随机推荐

  1. 演练5-5:Contoso大学校园管理系统5

    Contoso University示例网站演示如何使用Entity Framework 5创建ASP.NET MVC 4应用程序. Entity Framework有三种处理数据的方式:  Data ...

  2. export和import实现模块化

    export和import实现模块化 阅读目录 ES6的模块化的基本规则或特点: 下面列出几种import和export的基本语法: ES6导入的模块都是属于引用: 循环依赖的问题: 浏览器兼容: 参 ...

  3. Step by step guide to set up master and slave machines(转)

    Note: There is no need to install Jenkins on the slave machine. On your master machine go to Manage ...

  4. Solr部署详解

    Solr部署详解 时间:2013-11-24 方式:转载 目录 1 solr概述 1.1 solr的简介 1.2 solr的特点 2 Solr安装 2.1 安装JDK 2.2 安装Tomcat 2.3 ...

  5. CentOS6使用第三方yum源安装更多rpm软件包

    引言:       CentOS自带的yum源中rpm包数量有限,很多时候找不到我们需的软件包,(例如:要安装网络连接查看软件iftop,默认设置下无法使用yum命令安装),下面教大家在CentOS ...

  6. 第14周 项目三-OOP版电子词典

    做一个简单的电子词典.在文件dictionary.txt中,保存的是英汉对比的一个词典,词汇量近8000个,英文.中文释义与词性间用'\t'隔开. (1)编程序,由用户输入英文词.显示词性和中文释义. ...

  7. 巧用test判断来写shell脚本

    感觉最近很忙啊,阿里巴巴和百度马上就要笔试了,算法神马的还没有看..还是安心学习linux吧,决定在接下来的一周里,每天写一个shell script #!/bin/bash #输出提示语句,请输入一 ...

  8. API通用设计原则

    什么是好的API? ·        完备(Be Complete) 对确定重点支持的用户场景具有完备的功能支持.就是说,用户通过对一组API的调用能够完成预期的功能. ·        不冗余(Be ...

  9. Qt中Ui名字空间以及setupUi函数的原理和实现

    用最新的QtCreator选择GUI的应用会产生含有如下文件的工程 下面就简单分析下各部分的功能. .pro文件是供qmake使用的文件,不是本文的重点[不过其实也很简单的],在此不多赘述. 所以呢, ...

  10. 《WCF技术剖析》博文系列汇总[持续更新中]

    原文:<WCF技术剖析>博文系列汇总[持续更新中] 近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析(卷1)>的写作,一直无暇管理自己的Blog.在<WCF技术剖 ...