Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all references to an object in python

What is a good way to find all of the references to an object in python?

The reason I ask is that it looks like we have a "memory leak". We are uploading image files to the server from a web browser. Each time we do this, the memory usage on the server goes up proportionately to the size of the file that was just uploaded. This memory is never getting released by the python garbage collection, so I'm thinking that there are probably stray references pointing to the image data that are not getting deleted or going out of scope, even at the end of each request.

I figure it would be nice to be able to ask python: "What references are still pointing to this memory?" so that I can figure out what is keeping the garbage collection from freeing it.

Currently we are running Python and Django on a Heroku server.

like image 232
Chris Dutrow Avatar asked Aug 09 '12 20:08

Chris Dutrow


People also ask

How do you find the number of references and objects in Python?

Every object in Python has a reference count and a pointer to a type. We can get the current reference count of an object with the sys module. You can use sys. getrefcount(object), but keep in mind that passing in the object to getrefcount() increases the reference count by 1.

What is REF () in Python?

A reference is a name that refers to the specific location in memory of a value (object). References take the form of variables, attributes, and items. In Python, a variable or other reference has no intrinsic type.

Is multiple references to same object possible in Python?

The net effect is that the variables x and y wind up referencing the same object. This situation, with multiple names referencing the same object, is called a Shared Reference in Python. This statement causes the creation of a new object and made y to reference this new object.


1 Answers

Python's gc module has several useful functions, but it sounds like gc.get_referrers() is what you're looking for. Here's an example:

import gc   def foo():     a = [2, 4, 6]     b = [1, 4, 7]      l = [a, b]     d = dict(a=a)     return l, d  l, d = foo() r1 = gc.get_referrers(l[0]) r2 = gc.get_referrers(l[1])  print r1 print r2 

When I run that, I see the following output:

[[[2, 4, 6], [1, 4, 7]], {'a': [2, 4, 6]}] [[[2, 4, 6], [1, 4, 7]]] 

You can see that the first line is l and d, and the second line is just l.

In my brief experiments, I've found that the results are not always this clean. Interned strings and tuples, for example, have more referrers than you would expect.

like image 152
Don Kirkby Avatar answered Sep 28 '22 04:09

Don Kirkby