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. python groupby

    groupby() 将key函数作用于原循环器的各个元素.根据key函数结果,将拥有相同函数结果的元素分到一个新的循环器.每个新的循环器以函数返回结果为标签. 这就好像一群人的身高作为循环器.我们可以 ...

  2. Union - Find 、 Adjacency list 、 Topological sorting Template

    Find Function Optimization: After Path compression: int find(int x){ return root[x] == x ? x : (root ...

  3. cairo graphics.org

    cairographics.org Latest news: 2013-08-26: cairo 1.12.16 snapshot available 2013-02-10: cairo 1.12.1 ...

  4. 【iOS开发-72】设置状态栏的两种方式、程序生命周期以及更好地理解几大类(对象)之间的关系

    (1)设置状态栏的2种方式 --第一种方式就是我们在控制器中设置,系统默认就是交给视图控制器去管理的,这样不同视图控制器能够自己定义不同的状态栏例如以下: -(BOOL)prefersStatusBa ...

  5. 关于js基础easy忘记的那些事儿

    1.Number() 通过这个函数转化后的值仅仅有两个:数值和NaN,通过parseInt也能转化为数值.可是像"134df"转化后的值为134,而Number("134 ...

  6. last期末作业

    功能:每人完成一个新闻发布系统,包括系统的前台访问和后台管理. 要求: 1.使用ASP.NET MVC4开发. 2.在完成基本功能后,可以利用本学期所学的知识进行扩展. 3.完成日期为2013年12月 ...

  7. javascript笔记整理(对象的继承顺序、分类)

    Object.prototype.say=function(){ alert("我是顶层的方法"); } children.prototype=new parent(); pare ...

  8. 互联网组织的未来:剖析GitHub员工的任性之源(转)

    如果有这么家任性的公司,没有所谓“经理人”这一层,人都在做自己喜欢的事情,并且创造价值,而其他的事情,就顺其自然让他发生.这里能节省多少官僚主义带来的浪费?这样的公司得跑得有多快?得有多少无谓的冲突消 ...

  9. 基于visual Studio2013解决C语言竞赛题之1026判断排序

          题目 解决代码及点评 /********************************************************************** ...

  10. 高焕堂《android从程序员到架构师之路》 YY讲坛直面大师学习架构设计

    <android从程序员到架构师之路>YY讲坛活动:  sundy携手高焕堂老师全程YY答疑 与大师一起,分享android技术 时间:7月21日下午2:00   报名联系QQ:22243 ...