『Python』内存分析_List对象内存占用分析
Posted hellcat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『Python』内存分析_List对象内存占用分析相关的知识,希望对你有一定的参考价值。
『Python』内存分析_下_list和array的内存增长模式
list声明后结构大体分为3部分,变量名称--list对象(结构性数据+指针数组)--list内容,其中id表示的是list对象的位置,
v引用变量名称,v[:]引用list对象,此规则对python其他序列结构也成立,以下示范可用id佐证,
a=b时,a和b指向同一个list对象
a=b[:]时,a的list对象和b的list对象指向同一个list内容
Q1:元素存储地址是否连续
首先见得的测试一下list对象存储的内容(结构3)的内存地址,
In [1]: a=[1,2,3,‘a‘,‘b‘,‘c‘,‘de‘,[4,5]] In [2]: id(a) Out[2]: 139717112576840 In [3]: for i in a: ...: print(id(i)) ...: 139717238769920 139717238769952 139717238769984 139717239834192 139717240077480 139717240523888 139717195281104 139717112078024 In [4]: for i in a[6]: ...: print(id(i)) ...: 139717240220952 139717240202048 In [5]: for i in a[7]: ...: print(id(i)) ...: 139717238770016 139717238770048
然后看一下相对地址,
In [6]: for i in a: ...: print(id(i)-139717238769920) ...: 0 32 64 1064272 1307560 1753968 -43488816 -126691896 In [7]: for i in a[6]: ...: print(id(i)-139717238769920) ...: 1451032 1432128 In [8]: for i in a[7]: ...: print(id(i)-139717238769920) ...: 96 128
可见,对于list对象,其元素内容并不一定线性存储,但是由于内存分配的问题,会出现线性存储的假象,当元素出现容器或者相对前一个元素类型改变时,内存空间就会不再连续。
Q2:list对象地址和元素地址是否连续
其实Q1已经回答了这个问题,毕竟元素地址本身就不连续,不过我们还是测试了一下,
In [22]: id(a[0])-id(a) Out[22]: 126193080
相差甚远,而且我们分析源码可知,list对象主体是一个指针数组,也就是id(a)所指的位置主体是一个指向元素位置的指针数组,当然还有辅助的对象头信息之类的(python中几个常见的“黑盒子”之 列表list)。
Q3:list对象(不含元素)占用内存情况分析
In [16]: sys.getsizeof([1,2,3,‘a‘,‘b‘,‘c‘,‘de‘]) Out[16]: 120 In [17]: sys.getsizeof([1,2,3,‘a‘,‘b‘,‘c‘]) Out[17]: 112 In [18]: sys.getsizeof([1,2,3,‘a‘,‘b‘]) Out[18]: 104
可见,list每一个对象占用8字节32位空间,我们来看切片,
In [20]: sys.getsizeof(a[:3]) Out[20]: 88 In [21]: sys.getsizeof(a[:4]) Out[21]: 96 In [23]: sys.getsizeof(a[3:4]) Out[23]: 72 In [24]: sys.getsizeof(a[3:5]) Out[24]: 80
切片对象也是每个元素占8字节,但是切片也是list对象,即使从中间切(不切头),也会包含头信息的存储占用。
附注
1、[0]和[:1]的不同
In [30]: a[0] Out[30]: 1 In [31]: a[:1] Out[31]: [1]
2、空list占用空间
In [32]: sys.getsizeof([]) Out[32]: 64
以上是关于『Python』内存分析_List对象内存占用分析的主要内容,如果未能解决你的问题,请参考以下文章
JVM技术专题 Java各种类型对象占用内存情况分析「下篇」
JVM技术专题 Java各种类型对象占用内存情况分析「上篇」