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. itextsharp生成pdf后的直接打印问题

    原文 itextsharp生成pdf后的直接打印问题 小弟这两天用itextsharp生成pdf文档,生成的pdf可以直接保存在指定路径的文件夹下,可是user不想保存,想要点一下button,就可以 ...

  2. android 配置环境变量

    在创建AVD时,在DOS下输入android list targets 会出现android不是内部或外部命令,如图-1.这主要是没有配置好android sdk环境变量所致的. 图-1   andr ...

  3. Ubuntu 14.04下安装GitLab指南

    摘要 GitLab 是一个用于仓库管理系统的开源项目.使用Git作为代码管理工具,并在此基础上搭建起来的web服务. 在GitLab的官方网站上面对Ubuntu的支持也是很好的,有比较详尽的安装指南. ...

  4. Git命令非主流札记

    使用git做开发的版本管理也有一年半之多了,但是始终都是常用的branch commit status diff push等一些再常用不过的命令,最近闲下来,打算学习一下高端用法,所以就静下心来好好读 ...

  5. 使用Xshell生成key,避免password登录linux

    我们通常Xshell使用命令ssh user@ip远程登录linux,这将促使我们进入password更麻烦的,通缉免费password日志的话,我们可以生成相应的key.然后把遥控器server上, ...

  6. 项目优化经验分享(六)SVN冲突和处理

    上一篇博客我们分享了新增需求的确定思想<站在全局看问题>.今天我们来分享项目开发中SVN冲突的解决经验:SVN冲突和处理! 引言 开发过项目的人都知道,公司开发一个项目都会使用到版本号控制 ...

  7. 三种java 去掉字符串中的重复字符函数

    三种java 去掉字符串中的重复字符函数 public static void main(string[] args) { system.out.println(removerepeatedchar( ...

  8. Internet基础

    互联网是什么? Internet是一个互联网,它是将提供不同服务的,使用不同技术的,具有不同功能的物理网络互连起来而形成的. TCP/IP是一个协议集,它对Internet中主机的寻址方式,主机的命名 ...

  9. javascript 浏览器兼容性写法

    var event = window.event || arguments.callee.caller.arguments[0]; // 获取event对象 event = event.srcElem ...

  10. POJ 2250(最长公共子序列 变形)

    Description In a few months the European Currency Union will become a reality. However, to join the ...