我正在使用iPython运行代码。我想知道是否有任何模块或命令可以让我检查对象的内存使用情况。例如:
In [1]: a = range(10000)
In [2]: %memusage a
Out[2]: 1MB
类似于%memusage <object>
这样的语句,返回对象使用的内存。
重复
我正在使用iPython运行代码。我想知道是否有任何模块或命令可以让我检查对象的内存使用情况。例如:
In [1]: a = range(10000)
In [2]: %memusage a
Out[2]: 1MB
类似于%memusage <object>
这样的语句,返回对象使用的内存。
重复
很不幸,这是不可能的,但有一些方法可以近似计算答案:
对于非常简单的对象(例如 int、字符串、浮点数、双精度浮点数等),它们更多地表示为简单的 C 语言类型,您可以像 John Mulder 的解决方案一样简单地计算字节数。
对于更复杂的对象,一个很好的近似值是使用 cPickle.dumps 将对象序列化为字符串。该字符串的长度是存储对象所需的内存量的很好近似。
解决方案2存在一个大问题,即对象通常包含对其他对象的引用。例如,dict 包含字符串键和其他对象作为值。那些其他对象可以是共享的。由于 pickle 总是尝试完成对对象的完整序列化,因此它将始终高估存储对象所需的内存量。
如果您正在使用numpy数组,则可以使用属性ndarray.nbytes
来评估其在内存中的大小:
from pylab import *
d = array([2,3,4,5])
d.nbytes
#Output: 32
更新:这里有另一个更加详细的用于估计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
我一直在尝试弄清楚如何为自己做到这一点。我在此页面和其他页面上尝试了几种解决方案。然后,我进行了一些搜索,并发现了https://ipython-books.github.io/44-profiling-the-memory-usage-of-your-code-with-memory_profiler/,该网页似乎提供了一种替代方案。解决方案的要点:在ipython中使用%mprun
。
pip install memory_profiler
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)]
看起来符合我们的预期。