关于python:如何检查iPython中对象的内存使用情况?

How can I check the memory usage of objects in iPython?

我正在使用ipython运行我的代码。我想知道是否有任何模块或命令允许我检查对象的内存使用情况。例如:

1
2
3
In [1]: a = range(10000)
In [2]: %memusage a
Out[2]: 1MB

类似于%memusage ,返回对象使用的内存。

复制

Find out how much memory is being used by an object in Python


不幸的是,这是不可能的,但有许多方法可以近似得出答案:

  • 对于非常简单的对象(例如int、strings、float、doubles),这些对象或多或少被表示为简单的C语言类型,您可以使用john mulder的解决方案简单地计算字节数。

  • 对于更复杂的对象,一个好的近似方法是使用cpickle.dumps将对象序列化为字符串。字符串的长度与存储对象所需的内存量非常接近。

  • 解决方案2存在一个很大的障碍,即对象通常包含对其他对象的引用。例如,dict包含字符串键和其他对象作为值。这些其他对象可能是共享的。因为pickle总是尝试对对象进行完整的序列化,所以它总是高估存储对象所需的内存量。


    如果您使用的是numpy数组,那么可以使用属性ndarray.nbytes来计算其在内存中的大小:

    1
    2
    3
    4
    from pylab import *  
    d = array([2,3,4,5])  
    d.nbytes
    #Output: 32


    更新:这是另一个,也许更彻底的方法来估计一个python对象的大小。

    下面是一个处理类似问题的线程

    建议的解决方案是写你自己的…使用对原语的已知大小、Python的对象开销和内置容器类型的大小的一些估计。

    由于代码没有那么长,下面是它的直接副本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    def sizeof(obj):
       """APPROXIMATE memory taken by some Python objects in
        the current 32-bit CPython implementation.

        Excludes the space used by items in containers; does not
        take into account overhead of memory allocation from the
        operating system, or over-allocation by lists and dicts.
       """

        T = type(obj)
        if T is int:
            kind ="fixed"
            container = False
            size = 4
        elif T is list or T is tuple:
            kind ="variable"
            container = True
            size = 4*len(obj)
        elif T is dict:
            kind ="variable"
            container = True
            size = 144
            if len(obj) > 8:
                size += 12*(len(obj)-8)
        elif T is str:
            kind ="variable"
            container = False
            size = len(obj) + 1
        else:
            raise TypeError("don't know about this kind of object")
        if kind =="fixed":
            overhead = 8
        else: #"variable"
            overhead = 12
        if container:
            garbage_collector = 8
        else:
            garbage_collector = 0
        malloc = 8 # in most cases
        size = size + overhead + garbage_collector + malloc
        # Round to nearest multiple of 8 bytes
        x = size % 8
        if x != 0:
            size += 8-x
            size = (size + 8)
        return size