怎么查看python中对象占用的内存大小
sys.getsizeof() 查看内存占用
1、Python在sys模块提供了一个获取对象内存占用的基础方法sys.getsizeof,使用示例:
import sys
a = 1
b = 'b'
c = (1, 1)
d = [1]
e = {1}
f = {1: 1}
print(sys.getsizeof(a)) # 28
print(sys.getsizeof(b)) # 50
print(sys.getsizeof(c)) # 56
print(sys.getsizeof(d)) # 64
print(sys.getsizeof(e)) # 216
print(sys.getsizeof(f)) # 232
sys.getsizeof(object[, default])
以字节(byte)为单位返回对象大小。 这个对象可以是任何类型的对象。 所以内置对象都能返回正确的结果 但不保证对第三方扩展有效,因为和具体实现相关。
......
getsizeof()
调用对象的__sizeof__
方法,如果对象由垃圾收集器管理, 则会加上额外的垃圾收集器开销。
python中万物皆对象,int,str, list, dict, set, tuple皆是对象。包括所有类型的常量与变量,整型,布尔型,甚至函数。
# everythin in python is object
def fuction():
return
print isinstance(True, object)
print isinstance(0, object)
print isinstance('a', object)
print isinstance(fuction, object)
2、但是sys.getsizeof() 对复杂结构不适用
一个简单例子说明该方法为什么不适用于复杂结构:
a = {'a': 'a'}
b = {'b': 'b'}
c = [a, b]
print(getsizeof(a)) # 232
print(getsizeof(b)) # 232
print(getsizeof(c)) # 72
例子中c包含了a和b,按理说大小至少是a和b的加和,但是c却只是一个list大小。
因为sys.getsizeof()只会获取对象最外层的结构大小,python中都是地址引用,sys.getsizeof()不会将对象包含的地址引用指向的对象大小再计算在内。即该函数计算的是对象本身所占用的内存大小,而不是对象引用的其他对象所占用的内存大小。
python官方文档的解释:
所有内建对象返回的结果都是正确的,但对于第三方扩展不一定正确,因为这与具体实现有关。只计算直接分配给对象的内存消耗,不计算它所引用的对象的内存消耗。
pympler.asizeof() 查看内存占用
python提供一个更高级的库pympler
可以用来计算对象的内存占用大小。pympler
库提供了asizeof()
函数,可以更准确地计算一个对象及其引用的其他对象的内存总大小。使用示例:
from pympler import asizeof
my_dict = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
}
print(asizeof.asizeof(my_dict)) # 输出结果:408
上述示例中,创建了一个包含3个键值对的字典my_dict
,并使用asizeof()
函数计算该字典及其引用的其他对象所占用的内存大小。结果显示为408字节。
使用递归去获取引用对象的大小加和计算
1、python官方文档给出了一个解决办法recursive sizeof recipe
from __future__ import print_function
from sys import getsizeof, stderr
from itertools import chain
from collections import deque
try:
from reprlib import repr
except ImportError:
pass
def total_size(o, handlers={}, verbose=False):
""" Returns the approximate memory footprint an object and all of its contents.
Automatically finds the contents of the following builtin containers and
their subclasses: tuple, list, deque, dict, set and frozenset.
To search other containers, add handlers to iterate over their contents:
handlers = {SomeContainerClass: iter,
OtherContainerClass: OtherContainerClass.get_elements}
"""
dict_handler = lambda d: chain.from_iterable(d.items())
all_handlers = {tuple: iter,
list: iter,
deque: iter,
dict: dict_handler,
set: iter,
frozenset: iter,
}
all_handlers.update(handlers) # user handlers take precedence
seen = set() # track which object id's have already been seen
default_size = getsizeof(0) # estimate sizeof object without __sizeof__
def sizeof(o):
if id(o) in seen: # do not double count the same object
return 0
seen.add(id(o))
s = getsizeof(o, default_size)
if verbose:
print(s, type(o), repr(o), file=stderr)
for typ, handler in all_handlers.items():
if isinstance(o, typ):
s += sum(map(sizeof, handler(o)))
break
return s
return sizeof(o)
memory_profiler用来分析每行代码的内存使用情况
只需要给目标函数装上profile装饰器,就可以逐行分析函数代码的内存使用情况。使用示例:
import memory_profiler as mem
print(mem.memory_usage())
gen=(i for i in range(1000000))
print(type(gen))
print(mem.memory_usage())
l1=[i for i in range(1000000)]
print(mem.memory_usage())
print(type(l1))
from memory_profiler import profile
@profile # 也可以对当前函数添加装饰器来实现
def fun1(num):
for i in num:
print(i)
fun1(l1)
# [32.5]
# <class ‘generator’>
# [32.50390625]
# [71.86328125]
# <class ‘list’>
line_profiler 是用于对函数进行逐行分析的模块,只需要通过装饰器,就可以计算出函数内每一行代码的执行时间,以提供时间维度的性能诊断。memory_profiler 用于提供内存维度的性能诊断。
后话
对象内存占用与 Python 版本以及操作系统版本关系密切。
只需要给目标函数装上profile装饰器,就可以逐行分析函数代码的内存使用情况。使用示例:
内存优化技巧
- 使用生成器(Generator)而不是列表(List):生成器是一种延迟计算的迭代器。它在每次迭代时生成一个元素,而不是一次性生成所有元素。这样可以避免将大量数据存储在内存中,提高性能。
- 使用
del
语句手动删除不再使用的对象:Python具有自动内存管理的特性,但是它无法判断是否仍然需要某个对象。可以使用del
语句手动删除不再使用的对象,释放内存空间。 - 使用NumPy数组代替Python列表:NumPy是一个科学计算库,它提供了高性能的多维数组对象。相比于Python列表,NumPy数组占用的内存更小,操作更快。
- 使用内存映射(Memory Mapping):内存映射是一种将磁盘上的文件映射到内存中的技术。通过内存映射,可以避免将整个文件加载到内存中,减少内存占用。
sys.getsizeof()查看内存:Python复杂对象计算内存占用_python 对象占用内存计算-CSDN博客
安装memory_profiler包计算内存:python程序内存使用统计_python3 内存统计-CSDN博客
python程序内存使用统计_python3 内存统计-CSDN博客
如何查看各种python序列/容器的形状/长度是多少?python 查看对象内存占用和对象形状/长度的方法小结-__size__of,sys.getsizeof(),ndarray.size,ndarray.shape_python查看对象占用内存-CSDN博客python各类对象占用内存情况说明步进
- python内置的total_size(obj)函数
- pympler.asizeof()计算内存大小、以及内存优化方法Python 计算Python中对象所占用的内存|极客教程
python删除对象:Python del:删除对象_python del 撖寡情-CSDN博客
python del清内存_mob649e8157aaee的技术博客_51CTO博客
垃圾回收机制:能让你更早下班的Python垃圾回收机制_51CTO博客_python垃圾回收机制Python-垃圾回收 | Johney ZhengPython的内存管理以及垃圾回收_python内存回收太慢-CSDN博客
内存优化策略: