如何在Python中获得对象在内存中占用的大小?


当前回答

如果性能不是问题,最简单的解决方案是pickle和测量:

import pickle

data = ...
len(pickle.dumps(data))

其他回答

我用这个技巧…May在小对象上不准确,但我认为对于复杂对象(如pygame surface)比sys.getsizeof()更准确。

import pygame as pg
import os
import psutil
import time


process = psutil.Process(os.getpid())
pg.init()    
vocab = ['hello', 'me', 'you', 'she', 'he', 'they', 'we',
         'should', 'why?', 'necessarily', 'do', 'that']

font = pg.font.SysFont("monospace", 100, True)

dct = {}

newMem = process.memory_info().rss  # don't mind this line
Str = f'store ' + f'Nothing \tsurface use about '.expandtabs(15) + \
      f'0\t bytes'.expandtabs(9)  # don't mind this assignment too

usedMem = process.memory_info().rss

for word in vocab:
    dct[word] = font.render(word, True, pg.Color("#000000"))

    time.sleep(0.1)  # wait a moment

    # get total used memory of this script:
    newMem = process.memory_info().rss
    Str = f'store ' + f'{word}\tsurface use about '.expandtabs(15) + \
          f'{newMem - usedMem}\t bytes'.expandtabs(9)

    print(Str)
    usedMem = newMem

在我的windows 10, python 3.7.3,输出是:

store hello          surface use about 225280    bytes
store me             surface use about 61440     bytes
store you            surface use about 94208     bytes
store she            surface use about 81920     bytes
store he             surface use about 53248     bytes
store they           surface use about 114688    bytes
store we             surface use about 57344     bytes
store should         surface use about 172032    bytes
store why?           surface use about 110592    bytes
store necessarily    surface use about 311296    bytes
store do             surface use about 57344     bytes
store that           surface use about 110592    bytes

这可能不是最相关的答案,但我只对对象存储和检索感兴趣。因此将对象转储为pickle并检查pickle的大小就足够了

Pympler包的asizeof模块可以做到这一点。

使用方法如下:

from pympler import asizeof
asizeof.asizeof(my_object)

不像系统。Getsizeof,它适用于你自己创建的对象。它甚至可以与numpy一起工作。

>>> asizeof.asizeof(tuple('bcd'))
200
>>> asizeof.asizeof({'foo': 'bar', 'baz': 'bar'})
400
>>> asizeof.asizeof({})
280
>>> asizeof.asizeof({'foo':'bar'})
360
>>> asizeof.asizeof('foo')
40
>>> asizeof.asizeof(Bar())
352
>>> asizeof.asizeof(Bar().__dict__)
280
>>> A = rand(10)
>>> B = rand(10000)
>>> asizeof.asizeof(A)
176
>>> asizeof.asizeof(B)
80096

正如前面提到的,

可以通过设置option code=True来包含类、函数、方法、模块等对象的(字节)代码大小。

如果你需要实时数据的其他视图,请选择Pympler

模块muppy用于在线监控Python应用程序 和模块类跟踪器提供的生命周期的离线分析 选择Python对象。

你可以序列化对象,以获得与对象大小密切相关的度量值:

import pickle

## let o be the object whose size you want to measure
size_estimate = len(pickle.dumps(o))

如果您想测量无法pickle的对象(例如,由于lambda表达式),dill或cloudpickle可以是一种解决方案。

如果不想包含链接(嵌套)对象的大小,请使用sys.getsizeof()。

然而,如果你想计算嵌套在列表、字典、集、元组中的子对象——通常这就是你要找的——使用如下所示的递归深层sizeof()函数:

import sys
def sizeof(obj):
    size = sys.getsizeof(obj)
    if isinstance(obj, dict): return size + sum(map(sizeof, obj.keys())) + sum(map(sizeof, obj.values()))
    if isinstance(obj, (list, tuple, set, frozenset)): return size + sum(map(sizeof, obj))
    return size

你也可以在漂亮的工具箱中找到这个函数,以及许多其他有用的一行程序:

https://github.com/mwojnars/nifty/blob/master/util.py