Python里面如何查看对象所占用的内存?这里我们需要使用到Python内置的sys模块,sys模块负责程序与Python解释器的交互,提供了一系列的函数和变量,用于控制Python的运行时环境。
查看对象占用内存字节大小使用到sys模块的getsizeof()方法。
从上面代码中可以看出:
1.getsizeof方法可计算对象所占用内存字节数
2.getsizeof方法只计算对象直接占用的内存,而不计算对象内所引用对象的内存
看到这里可能有人疑惑,为什么同样的一个列表我这里申请的内存跟上图不一样?
其实这里跟Python解释器有关,32位的解释器创建对象时申请的内存空间要小于64位。
空对象并不“空”
在Python里面有个None表示什么都不是,大家是否好奇过这个None到底是什么?其实None也是一个对象,其类型为NoneType。我们所熟知空对象还有空字符串,空列表,空字典,空元组。当程序创建一个空对象时,这个空对象是否占用内存呢?
虽然都是空对象,但是这些对象在内存分配上并不为“空”。
天啊!空对象居然占用内存,为什么会这样呢?
除了None对象外,其他空对象都是容器,可以理解为创建这个容器本身就需要占用一定的内存,还有一部分内存是对象在初始化的时候预分配。这就是我们看到的空对象也占用这么大内存原因。
空对象并不为空,一部分原因是 Python 解释器为它们预分配了一些初始空间。在不超出初始内存的情况下,每次新增元素,就使用已有内存,因而避免了再去申请新的内存。
内存扩容
创建对象的时候只会分配少量的内存空间,在以后追加元素的对象占用内存必须扩容。那么是如何扩容?每次扩容多大?
下面我们来看下list,set,dict 三个对象的扩容过程
分别给三类可变对象添加 30个元素,看看结果如何:
从结果上我们可以看出来:
1.每次申请内存都是比实际需要内存要多,这种超额申请,主要是为了避免频繁申请内存,导致不必要的开销。
2.每次申请内存不是均匀申请,而是逐渐变大。
删除元素不会释放内存
新增元素的时候会申请新内存,那么删除元素是否新申请的内存是否会释放?
看下面的代码对比:
列表在一扩一缩后,虽然列表的元素回到原样,但是所占用的内存空间可没有自动释放啊。字典,集合等等可变对象同理。
空字典不等于空字典
pop方法是删除一个元素,并不会释放新申请的内存,clear方法是清空所有元素。
下面来看clear方法清空之后内存是否会释放。
先回忆下文章开篇讲的创建空对象讲的每个对象申请的内存,如下图:
调用clear方法后,获得三个空对象,计算每个对象占用的内存。
閱讀更多 沐雨軒7485 的文章