Python超詳細(xì)講解內(nèi)存管理機(jī)制
什么是內(nèi)存管理機(jī)制
python中創(chuàng)建的對象的時(shí)候,首先會(huì)去申請內(nèi)存地址,然后對對象進(jìn)行初始化,所有對象都會(huì)維護(hù)在一
個(gè)叫做refchain的雙向循環(huán)鏈表中,每個(gè)數(shù)據(jù)都保存如下信息:
1. 鏈表中數(shù)據(jù)前后數(shù)據(jù)的指針
2. 數(shù)據(jù)的類型
3. 數(shù)據(jù)值
4. 數(shù)據(jù)的引用計(jì)數(shù)
5. 數(shù)據(jù)的長度(list,dict..)
一、引用計(jì)數(shù)機(jī)制
引用計(jì)數(shù)增加:
1.1 對象被創(chuàng)建
1.2 對象被別的變量引用(另外起了個(gè)名字)
1.3 對象被作為元素,放在容器中(比如被當(dāng)作元素放在列表中)
1.4 對象被當(dāng)成參數(shù)傳遞到函數(shù)中
import sys a = [11,22] # 對象被創(chuàng)建 b = a # 對象被別的變量引用 c = [111,222,333,a] # 對象被作為元素,放在容器中 # 獲取對象的引用計(jì)數(shù) print(sys.getrefcount(a)) # 對象被當(dāng)成參數(shù)傳遞到函數(shù)中
最后的執(zhí)行結(jié)果是,a 這個(gè)變量被引用了4次

引用計(jì)數(shù)減少:
- 對象的別名被顯式的銷毀
- 對象的一個(gè)別名被賦值給其他對象 (例:比如原來的a=10,被改成a=100,此時(shí)10的引用計(jì)數(shù)就減少了)
- 對象從容器中被移除,或者容器被銷毀(例:對象從列表中被移除,或者列表被銷毀)
- 一個(gè)引用離開了它的作用域(調(diào)用函數(shù)的時(shí)候傳進(jìn)去的參數(shù),在函數(shù)運(yùn)行結(jié)束后,該參數(shù)的引用即被銷毀)
import sys del b # 對象的別名被顯式的銷毀 b = 999 # 對象的一個(gè)別名被賦值給其他對象 del c # 列表被銷毀(容器被銷毀) c.pop() # 把列表數(shù)據(jù)最后一個(gè)刪除掉(對象從容器中被移除)
二、數(shù)據(jù)池和緩存
數(shù)據(jù)池分為兩種:小整數(shù)池 和 大整數(shù)池
小整數(shù)池(-5到256之間的數(shù)據(jù))
運(yùn)行機(jī)制:Python自動(dòng)將 -5~256 的整數(shù)進(jìn)行了緩存到一個(gè)小整數(shù)池中,當(dāng)你將這些整數(shù)賦值給變量時(shí),并不會(huì)重新
創(chuàng)建對象,而是使用已經(jīng)創(chuàng)建好的緩存對象,當(dāng)刪除這些數(shù)據(jù)的引用時(shí),也不會(huì)進(jìn)行回收
超出-5到256的整數(shù)將不會(huì)在在緩存,會(huì)重新創(chuàng)建對象
例如:
對于超出-5到256的整數(shù)將不會(huì)在在緩存,Python會(huì)重新創(chuàng)建對象,返回id
# 場景1:數(shù)據(jù)為列表,不在-5~256 的范圍 >>> a = [11] >>> b = [11] >>> id(a),id(b) (1693226918600, 1693231858248) ========》 id 不一樣 # 場景二: 數(shù)據(jù)為整數(shù),在-5~256 的范圍 >>> aa = 11 >>> bb = 11 >>> id(aa),id(bb) (140720470385616, 140720470385616) id 一樣 # 場景三: 數(shù)據(jù)不在-5~256的范圍 >>> bb = -7 >>> aa = -7 >>> id(aa),id(bb) (1843518717904, 1843518717776) id 不一樣 # 場景四: 數(shù)據(jù)不在-5~256的范圍 >>> a = 257 >>> b = 257 >>> id(a),id(b) (2092420910928, 2092420911056) id 不一樣
大整數(shù)池(字符串駐留池 / intern機(jī)制)
優(yōu)點(diǎn):在創(chuàng)建新的字符串對象時(shí),會(huì)先在緩存池里面找是否有已經(jīng)存在的值相同的對象(標(biāo)識符,即只包含數(shù)字、字母、下劃線的字符串),如果有,則直接拿過來用(引用),避免頻繁的創(chuàng)建和銷毀內(nèi)存,提升效率
例如:
對于不在標(biāo)識符內(nèi)的數(shù)據(jù)將不會(huì)在在緩存,Python會(huì)重新創(chuàng)建對象,返回id
# 場景1: >>> a = '123adsf_' >>> b = '123adsf_' >>> id(a),id(b) (61173296, 61173296) ========》 id 一樣 # 場景二: >>> b1 = '123adsf_?' >>> b2 = '123adsf_?' >>> id(b1),id(b2) (61173376, 61173416) id 不一樣
緩存機(jī)制

對于python中常用內(nèi)置數(shù)據(jù)類型的緩存:
float:緩存100個(gè)對象
list: 80個(gè)對象
dict: 80個(gè)對象
set: 80個(gè)對象
元組:會(huì)根據(jù)元組數(shù)據(jù)的長度,分別緩存元組長度為0-20的對象
到此這篇關(guān)于Python超詳細(xì)講解內(nèi)存管理機(jī)制的文章就介紹到這了,更多相關(guān)Python內(nèi)存管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django2.1集成xadmin管理后臺所遇到的錯(cuò)誤集錦(填坑)
這篇文章主要介紹了Django2.1集成xadmin管理后臺所遇到的錯(cuò)誤集錦(填坑),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
如何利用Python實(shí)現(xiàn)自動(dòng)打卡簽到的實(shí)踐
簽到,都是規(guī)律性的操作,何嘗不寫一個(gè)程序加到Windows實(shí)現(xiàn)自動(dòng)簽到呢,本文就主要介紹了如何利用Python實(shí)現(xiàn)自動(dòng)打卡簽到的實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2021-12-12
Python鼠標(biāo)事件及坐標(biāo)獲取窗口和屏幕坐標(biāo)
這篇文章主要介紹了Python編程中如何通過鼠標(biāo)事件及坐標(biāo)獲取窗口坐標(biāo)和屏幕坐標(biāo)的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
VSCode設(shè)置類似Pycharm控制臺運(yùn)行Python顯示中間變量的步驟
Python中if __name__ == ''__main__''作用解析
Python爬蟲使用瀏覽器cookies:browsercookie過程解析

