310

How would you go about finding out how much memory is being used by an object? I know it is possible to find out how much is used by a block of code, but not by an instantiated object (anytime during its life), which is what I want.

Honest Abe
  • 8,430
  • 4
  • 49
  • 64
dwestbrook
  • 5,108
  • 3
  • 25
  • 20
  • Similar: http://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python – matt b Oct 06 '10 at 02:52
  • 1
    objgraph looks interesting: http://mg.pov.lt/objgraph/ –  Jan 28 '10 at 10:06
  • Graphical Test: http://stackoverflow.com/a/30008338/2087463 – tmthydvnprt Mar 13 '16 at 13:37
  • 1
    If it's an object of your class, you can be outgoing towards your users, and implement `__sizeof__(self)` for them. For example NumPy does that, and `a.__sizeof__()` is somewhat bigger (includes the object overhead), than `a.nbytes` - which is the number of bytes in the allocated array. – Tomasz Gandor Sep 30 '19 at 13:04
  • Another approach is to use pickle. See [this answer](https://stackoverflow.com/a/565382/420867) to a duplicate of this question. – drevicko Oct 16 '12 at 22:25

5 Answers5

207

Try this:

sys.getsizeof(object)

getsizeof() Return the size of an object in bytes. It calls the object’s __sizeof__ method and adds an additional garbage collector overhead if the object is managed by the garbage collector.

A recursive recipe

Stefan
  • 919
  • 2
  • 13
  • 24
Uzer
  • 3,054
  • 1
  • 17
  • 23
  • 13
    Does this sys.getsizeof(object) return value includes the real object size instead of their pointer's size as fserb said above? – Clock ZHONG May 08 '17 at 03:00
  • 38
    No, it will return the size of the pointer. – lstyls Jun 27 '17 at 01:10
  • 8
    What's the difference between this and `object.__sizeof__()`? It seems that `sys.getsizeof(object)` returns a slightly larger value. EDIT: The latter also includes the garbage collector overhead. – Mateen Ulhaq Nov 22 '18 at 17:22
  • 1
    I've found that `sys.getsizeof(object.copy)` often gives the correct value, where `sys.getsizeof(object)` gives you some far lower value (I guess the pointer size). – Andrew D. King Jan 08 '22 at 21:08
  • 1
    don't forget `import sys`! – elad silver May 31 '22 at 00:26
  • 3
    It is not right. I created a pytorch tensor in CPU and its shape is `(100000000,)`, `sys.getsizeof(x.copy)` shows 80. But the data type is float64. – GoingMyWay Jun 17 '22 at 02:29
  • Yeah, I'm getting something way to small as well, this is not a great solution... I'm trying to figure out how large a machine learning model is in memory because it's taking up too much memory when I try to load it. There are like tens of thousands of rows of data in this object... so it's definitely larger than the 80 bytes I'm getting back. – datacoder Sep 30 '22 at 21:45
155

There's no easy way to find out the memory size of a python object. One of the problems you may find is that Python objects - like lists and dicts - may have references to other python objects (in this case, what would your size be? The size containing the size of each object or not?). There are some pointers overhead and internal structures related to object types and garbage collection. Finally, some python objects have non-obvious behaviors. For instance, lists reserve space for more objects than they have, most of the time; dicts are even more complicated since they can operate in different ways (they have a different implementation for small number of keys and sometimes they over allocate entries).

There is a big chunk of code (and an updated big chunk of code) out there to try to best approximate the size of a python object in memory.

You may also want to check some old description about PyObject (the internal C struct that represents virtually all python objects).

Rob
  • 26,989
  • 16
  • 82
  • 98
fserb
  • 4,004
  • 2
  • 26
  • 23
  • 8
    @culix: Seems like that again is now used in the [Pympler](http://pythonhosted.org/Pympler/) module. – FriendFX Jun 07 '13 at 07:43
  • 2
    What if your object is pretty simple, such as a dict with an `Int -> (Int, Int)` mapping? In theory, calculating the size of such an object should be simple, right? – David Sanders Oct 28 '14 at 23:21
  • 2
    If a book has references, to other books, its size didn't increase. – j riv Feb 17 '22 at 12:27
8

I haven't any personal experience with either of the following, but a simple search for a "Python [memory] profiler" yield:

  • PySizer, "a memory profiler for Python," found at http://pysizer.8325.org/. However the page seems to indicate that the project hasn't been updated for a while, and refers to...

  • Heapy, "support[ing] debugging and optimization regarding memory related issues in Python programs," found at http://guppy-pe.sourceforge.net/#Heapy.

Hope that helps.

jcsalterego
  • 454
  • 2
  • 2
7

This must be used with care because an override on the objects __sizeof__ might be misleading.

Using the bregman.suite, some tests with sys.getsizeof output a copy of an array object (data) in an object instance as being bigger than the object itself (mfcc).

>>> mfcc = MelFrequencyCepstrum(filepath, params)
>>> data = mfcc.X[:]
>>> sys.getsizeof(mfcc)
64
>>> sys.getsizeof(mfcc.X)
>>>80
>>> sys.getsizeof(data)
80
>>> mfcc
<bregman.features.MelFrequencyCepstrum object at 0x104ad3e90>
rafaelvalle
  • 6,683
  • 3
  • 34
  • 36
3

For big objects you may use a somewhat crude but effective method: check how much memory your Python process occupies in the system, then delete the object and compare.

This method has many drawbacks but it will give you a very fast estimate for very big objects.

  • 5
    This is unlikely to be effective. Memory freed in a process does not have to be returned to the operating system, so looking for a decrease in memory use may not be accurate. – nobody Jun 30 '14 at 21:09
  • 15
    A similar approach of measuring python process resource usage before the object is created and after would be quite effective. – Antony Hatchkins Oct 24 '14 at 10:21
  • 7
    Don't think so @AntonyHatchkins as python memory manager do not necessarily get new memory from the operating systems. To some extent, memory pool is kept allocated even if not in use, so when there's a new request, it may be fulfilled without the need to request more memory from the operating system. In other words, this approach is unreliable for both creation and destruction of objects. – spider Apr 26 '17 at 13:15