『Python』內存分析_List對象內存占用分析
阿新 • • 發佈:2018-05-12
我們 nbsp 黑盒子 切片 color div int HR HA
『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對象內存占用分析