一、變量存哪了?
x = 10
當我們在p1.py中定義一個變量x = 10
,那么計算機把這個變量值10存放在哪里呢了?我們回顧計算機的三大核心組件為:CPU、內存和硬盤。一定不是CPU,那是存放在內存還是硬盤中了呢?我們再回顧變量運行的三個過程,如果我們沒有使用python解釋器運行p1.py這個文件,那么x=10
很明顯只是很普通的四個字符x、=、1、0。而只有Python解釋器運行了這個文件,那字符進入了內存,才會有變量這個概念。也就是說變量是存放在內存當中的。
變量存放在內存中這句話太寬泛了,我們把它具體化。現在想象我們在學校(電腦內存)里上課,學校每開一個班,學校都會開辟一個教室給這個班級上課用(存放變量值10),而班級的門牌號則是(變量名x)。也就是說,對於電腦內存這個大內存,每定義一個變量就會在這個大內存中開辟一個小空間,小空間內存放變量值10,然后內存給這個小空間一個變量名x(門牌號),x指向10。
二、Python垃圾回收機制
對於p1.py,如果我們再加上一段代碼x = 11
,大內存會開辟另一個小空間存儲變量值11,把變量值綁定另一個門牌號x,但是由於之前有x,所以大內存會解除x與10的連接,讓x與11連接。這個時候10由於沒有了門牌號,所以成為了python眼中的垃圾,python就會處理這個垃圾,釋放10的內存占用,這就是python的垃圾回收機制。而其他語言需要手動把10的內存占用釋放掉。
2.1 引用計數
從上述的解釋我們可以知道只要某個變量值綁定着門牌號,就不是垃圾,反之變量值沒有綁定着門牌號,這個變量值就是垃圾,python就會自動清理這個垃圾。這里我們對於這個門牌號給定一個專業的解釋,在python中這個門牌號被稱作引用計數。
x = 10 # 10引用計數加1為1
y = x # 10引用計數加1為2
x = 11 # 10引用計數減1為1;11引用計數加1為1
del y # 10引用計數減1為0,觸發python垃圾回收機制,python清理10的內存占用
上述代碼就是一個引用計數加減的過程。
三、小整數池
對於上一節講的引用計數,需要注意的是:Python實現int的時候有個小整數池。為了避免因創建相同的值而重復申請內存空間所帶來的效率問題, Python解釋器會在啟動時創建出小整數池,范圍是[-5,256],該范圍內的小整數對象是全局解釋器范圍內被重復使用,永遠不會被垃圾回收機制回收。
在pycharm中運行python程序時,pycharm出於對性能的考慮,會擴大小整數池的范圍,其他的字符串等不可變類型也都包含在內一便采用相同的方式處理了,我們只需要記住這是一種優化機制,至於范圍到底多大,無需細究。