41

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

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

类似%memusage <object>并返回对象使用的内存。

复制

找出 Python 中的对象正在使用多少内存

4

4 回答 4

65

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

  1. 对于或多或少表示为简单 C 语言类型的非常简单的对象(例如整数、字符串、浮点数、双精度数),您可以像John Mulder 的解决方案一样简单地计算字节数。

  2. 对于更复杂的对象,一个很好的近似方法是使用 cPickle.dumps 将对象序列化为字符串。字符串的长度很好地近似于存储对象所需的内存量。

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

于 2009-02-19T13:50:09.897 回答
23

如果您使用的是numpy array,那么您可以使用该属性ndarray.nbytes来评估其在内存中的大小:

from pylab import *   
d = array([2,3,4,5])   
d.nbytes
#Output: 32
于 2013-03-23T19:30:46.750 回答
14

更新:这是另一个估计 python 对象大小的可能更彻底的方法。

这是一个解决类似问题 的线程

提出的解决方案是编写自己的...使用对已知原语大小、python 的对象开销和内置容器类型大小的一些估计。

由于代码不长,这里直接复制:

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
于 2009-02-19T04:07:23.133 回答
2

我试图弄清楚如何为自己做到这一点。我在此页面和其他页面上尝试了几种解决方案。然后我做了一些搜索,发现了https://ipython-books.github.io/44-profiling-the-memory-usage-of-your-code-with-memory_profiler/,这似乎提供了另一种解决方案。解决方案的要点:%mprun在 ipython 中使用。

  1. 首先,安装 memory_profiler:pip install memory_profiler
  2. 启动 ipython 并加载 memory_profiler:%load_ext memory_profiler
  3. 例如,在物理文件中创建一个函数myfunc.py(重要:%mprun 只能用于物理文件中定义的函数)。在函数中创建有问题的对象,例如:
# myfunc.py
def myfunc():
    # create the object, e.g.
    a = [*range(10000)]
from myfunc import myfunc
%mprun -T mprof -f myfunc myfunc()

生成文件 mprof. 内容也显示:

Line #    Mem usage    Increment   Line Contents
================================================
     1     49.1 MiB     49.1 MiB   def myfunc():
     2                                 # create the object, e.g.
     3     49.4 MiB      0.3 MiB       a = [*range(10000)]

根据第 3 行的内容,我们知道所使用的内存a为 0.3 MiB。

让我们试试a = [*range(100000)]

# myfunc1.py
def myfunc1():
    # create the object, e.g.
    a = [*range(100000)]

from myfunc1 import myfunc1
%mprun -T mprof1 -f myfunc1 myfunc1()

Line #    Mem usage    Increment   Line Contents
================================================
     1     49.2 MiB     49.2 MiB   def myfunc1():
     2                                 # create the object, e.g.
     3     52.3 MiB      3.0 MiB       a = [*range(100000)]

似乎符合我们的预期。

于 2019-10-13T10:18:34.830 回答