Python的內(nèi)存管理主要有三種機(jī)制:引用計(jì)數(shù)機(jī)制,垃圾回收機(jī)制和內(nèi)存池機(jī)制。

創(chuàng)新互聯(lián)公司是一家企業(yè)級云計(jì)算解決方案提供商,超15年IDC數(shù)據(jù)中心運(yùn)營經(jīng)驗(yàn)。主營GPU顯卡服務(wù)器,站群服務(wù)器,成都多線機(jī)房,海外高防服務(wù)器,大帶寬服務(wù)器,動態(tài)撥號VPS,海外云手機(jī),海外云服務(wù)器,海外服務(wù)器租用托管等。
引用計(jì)數(shù)機(jī)制
簡介
python內(nèi)部使用引用計(jì)數(shù),來保持追蹤內(nèi)存中的對象,Python內(nèi)部記錄了對象有多少個引用,即引用計(jì)數(shù),當(dāng)對象被創(chuàng)建時就創(chuàng)建了一個引用計(jì)數(shù),當(dāng)對象不再需要時,這個對象的引用計(jì)數(shù)為0時,它被垃圾回收。
特性
1.當(dāng)給一個對象分配一個新名稱或者將一個對象放入一個容器(列表、元組或字典)時,該對象的引用計(jì)數(shù)都會增加。
2.當(dāng)使用del對對象顯示銷毀或者引用超出作用于或者被重新賦值時,該對象的引用計(jì)數(shù)就會減少。
3.可以使用sys.getrefcount()函數(shù)來獲取對象的當(dāng)前引用計(jì)數(shù)。多數(shù)情況下,引用計(jì)數(shù)要比我們猜測的大的多。對于不可變數(shù)據(jù)(數(shù)字和字符串),解釋器會在程序的不同部分共享內(nèi)存,以便節(jié)約內(nèi)存。
垃圾回收機(jī)制
特性
1.當(dāng)內(nèi)存中有不再使用的部分時,垃圾收集器就會把他們清理掉。它會去檢查那些引用計(jì)數(shù)為0的對象,然后清除其在內(nèi)存的空間。當(dāng)然除了引用計(jì)數(shù)為0的會被清除,還有一種情況也會被垃圾收集器清掉:當(dāng)兩個對象相互引用時,他們本身其他的引用已經(jīng)為0了。
2.垃圾回收機(jī)制還有一個循環(huán)垃圾回收器, 確保釋放循環(huán)引用對象(a引用b, b引用a, 導(dǎo)致其引用計(jì)數(shù)永遠(yuǎn)不為0)。
內(nèi)存池機(jī)制
簡介
在Python中,許多時候申請的內(nèi)存都是小塊的內(nèi)存,這些小塊內(nèi)存在申請后,很快又會被釋放,由于這些內(nèi)存的申請并不是為了創(chuàng)建對象,所以并沒有對象一級的內(nèi)存池機(jī)制。這就意味著Python在運(yùn)行期間會大量地執(zhí)行malloc和free的操作,頻繁地在用戶態(tài)和核心態(tài)之間進(jìn)行切換,這將嚴(yán)重影響Python的執(zhí)行效率。為了加速Python的執(zhí)行效率,Python引入了一個內(nèi)存池機(jī)制,用于管理對小塊內(nèi)存的申請和釋放。
內(nèi)存池概念
內(nèi)存池的概念就是預(yù)先在內(nèi)存中申請一定數(shù)量的,大小相等的內(nèi)存塊留作備用,當(dāng)有新的內(nèi)存需求時,就先從內(nèi)存池中分配內(nèi)存給這個需求,不夠了之后再申請新的內(nèi)存。這樣做最顯著的優(yōu)勢就是能夠減少內(nèi)存碎片,提升效率。內(nèi)存池的實(shí)現(xiàn)方式有很多,性能和適用范圍也不一樣。
特性
1.Python提供了對內(nèi)存的垃圾收集機(jī)制,但是它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng)。
2.Pymalloc機(jī)制。為了加速Python的執(zhí)行效率,Python引入了一個內(nèi)存池機(jī)制,用于管理對小塊內(nèi)存的申請和釋放。
3.Python中所有小于256個字節(jié)的對象都使用pymalloc實(shí)現(xiàn)的分配器,而大的對象則使用系統(tǒng)的 malloc。
4.對于Python對象,如整數(shù),浮點(diǎn)數(shù)和List,都有其獨(dú)立的私有內(nèi)存池,對象間不共享他們的內(nèi)存池。也就是說如果你分配又釋放了大量的整數(shù),用于緩存這些整數(shù)的內(nèi)存就不能再分配給浮點(diǎn)數(shù)。
一、函數(shù)的定義
函數(shù)是指將一組語句的集合通過一個名字(函數(shù)名)封裝起來,想要執(zhí)行這個函數(shù),只需要調(diào)用函數(shù)名即可
特性:
減少重復(fù)代碼
使程序變得可擴(kuò)展
使程序變得易維護(hù)
二、函數(shù)的參數(shù)
2.1、形參和實(shí)參數(shù)
形參,調(diào)用時才會存在的值
實(shí)慘,實(shí)際存在的值
2.2、默認(rèn)參數(shù)
定義:當(dāng)不輸入?yún)?shù)值會有一個默認(rèn)的值,默認(rèn)參數(shù)要放到最后
2.3、 關(guān)鍵參數(shù)
定義: 正常情況下,給函數(shù)傳參數(shù)要安裝順序,不想按順序可以用關(guān)鍵參數(shù),只需要指定參數(shù)名即可,(指定了參數(shù)名的就叫關(guān)鍵參數(shù)),但是要求是關(guān)鍵參數(shù)必須放在位置參數(shù)(以位置順序確定對應(yīng)的參數(shù))之后
2.4、非固定參數(shù)
定義: 如你的函數(shù)在傳入?yún)?shù)時不確定需要傳入多少個參數(shù),就可以使用非固定參數(shù)
# 通過元組形式傳遞
# 通過列表形式傳遞
# 字典形式(通過k,value的方式傳遞)
# 通過變量的方式傳遞
三、函數(shù)的返回值
作用:
返回函數(shù)執(zhí)行結(jié)果,如果沒有設(shè)置,默認(rèn)返回None
終止函數(shù)運(yùn)行,函數(shù)遇到return終止函數(shù)
四、變量的作用域
全局變量和局部變量
在函數(shù)中定義的變量叫局部變量,在程序中一開始定義的變量叫全局變量
全局變量作用域整個程序,局部變量作用域是定義該變量的函數(shù)
當(dāng)全局變量與局部變量同名是,在定義局部變量的函數(shù)內(nèi),局部變量起作用,其他地方全局變量起作用
同級的局部變量不能互相調(diào)用
想要函數(shù)里邊的變量設(shè)置成全局變量,可用global進(jìn)行設(shè)置
五、特殊函數(shù)
5.1、嵌套函數(shù)
定義: 嵌套函數(shù)顧名思義就是在函數(shù)里邊再嵌套一層函數(shù)
提示 在嵌套函數(shù)里邊調(diào)用變量是從里往外依次調(diào)用,意思就是如果需要調(diào)用的變量在當(dāng)前層沒有就會去外層去調(diào)用,依次內(nèi)推
匿名函數(shù)
基于Lambda定義的函數(shù)格式為: lambda 參數(shù):函數(shù)體
參數(shù),支持任意參數(shù)。
匿名函數(shù)適用于簡單的業(yè)務(wù)處理,可以快速并簡單的創(chuàng)建函數(shù)。
# 與三元運(yùn)算結(jié)合
5.3、高階函數(shù)
定義:變量可以指向函數(shù),函數(shù)的參數(shù)可以接收變量,那么一個函數(shù)就可以接收另一個函數(shù)作為參數(shù),這種函數(shù)稱之為高階函數(shù) 只需要滿足一下任意一個條件,即是高階函數(shù)
接收一個或多個函數(shù)作為輸入
return返回另一個函數(shù)
5.4、遞歸函數(shù)
定義:一個函數(shù)可以調(diào)用其他函數(shù),如果一個函數(shù)調(diào)用自己本身,這個函數(shù)就稱為遞歸函數(shù)
在默認(rèn)情況下Python最多能遞歸1000次,(這樣設(shè)計(jì)師是為了防止被內(nèi)存被撐死)可以通過sys.setrecursionlimit(1500)進(jìn)行修改
遞歸實(shí)現(xiàn)過程是先一層一層的進(jìn),然后在一層一層的出來
必須有一個明確的條件結(jié)束,要不然就是一個死循環(huán)了
每次進(jìn)入更深層次,問題規(guī)模都應(yīng)該有所減少
遞歸執(zhí)行效率不高,遞歸層次過多會導(dǎo)致站溢出
# 計(jì)算4的階乘 4x3x2x1
# 打印數(shù)字從1-100
5.5、閉包現(xiàn)象
定義:內(nèi)層函數(shù)調(diào)用外層函數(shù)的變量,并且內(nèi)存函數(shù)被返回到外邊去了
閉包的意義:返回的函數(shù)對象,不僅僅是一個函數(shù)對象,在該函數(shù)外還包裹了一層作用域,這使得,該函數(shù)無論在何處調(diào)用,優(yōu)先使用自己外層包裹的作用域
Python提供了對內(nèi)存的垃圾收集機(jī)制,但是它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng)。
Python中所有小于256個字節(jié)的對象都使用pymalloc實(shí)現(xiàn)的分配器,而大的對象則使用系統(tǒng)的
malloc。另外Python對象,如整數(shù),浮點(diǎn)數(shù)和List,都有其獨(dú)立的私有內(nèi)存池,對象間不共享他們的內(nèi)存池。也就是說如果你分配又釋放了大量的
整數(shù),用于緩存這些整數(shù)的內(nèi)存就不能再分配給浮點(diǎn)數(shù)。
在Python中,許多時候申請的內(nèi)存都是小塊的內(nèi)存,這些小塊內(nèi)存在申請后,很快又會被釋放,由于這些內(nèi)存的申請并不是為了創(chuàng)建對象,所以并沒有對象一
級的內(nèi)存池機(jī)制。這就意味著Python在運(yùn)行期間會大量地執(zhí)行malloc和free的操作,頻繁地在用戶態(tài)和核心態(tài)之間進(jìn)行切換,這將嚴(yán)重影響
Python的執(zhí)行效率。為了加速Python的執(zhí)行效率,Python引入了一個內(nèi)存池機(jī)制,用于管理對小塊內(nèi)存的申請和釋放。這也就是之前提到的
由于python中萬物皆對象,所以python的存儲問題是對象的存儲問題。實(shí)際上,對于每個對象,python會分配一塊內(nèi)存空間去存儲它。
那么python是如何進(jìn)行內(nèi)存分配,如何進(jìn)行內(nèi)存管理,又是如何釋放內(nèi)存的呢?
總結(jié)起來有一下幾個方面:引用計(jì)數(shù),垃圾回收,內(nèi)存池機(jī)制
python內(nèi)部使用引用計(jì)數(shù),來保持追蹤內(nèi)存中的對象,Python內(nèi)部記錄了對象有多少個引用,即引用計(jì)數(shù)
1、對象被創(chuàng)建 a= 'abc'
2、對象被引用 b =a
3、對象被其他的對象引用 li = [1,2,a]
4、對象被作為參數(shù)傳遞給函數(shù):foo(x)
1、變量被刪除 del a 或者 del b
2、變量引用了其他對象 b = c 或者 a = c
3、變量離開了所在的作用域(函數(shù)調(diào)用結(jié)束) 比如上面的foo(x)函數(shù)結(jié)束時,x指向的對象引用減1。
4、在其他的引用對象中被刪除(移除) li.remove(a)
5、窗口對象本身被銷毀:del li,或者窗口對象本身離開了作用域。
即對象p中的屬性引用d,而對象d中屬性同時來引用p,從而造成僅僅刪除p和d對象,也無法釋放其內(nèi)存空間,因?yàn)樗麄円廊辉诒灰谩I钊虢忉尵褪牵h(huán)引用后,p和d被引用個數(shù)為2,刪除p和d對象后,兩者被引用個數(shù)變?yōu)?,并不是0,而python只有在檢查到一個對象的被引用個數(shù)為0時,才會自動釋放其內(nèi)存,所以這里無法釋放p和d的內(nèi)存空間
垃圾回收機(jī)制: ① 引用計(jì)數(shù) , ②標(biāo)記清除 , ③分帶回收
引用計(jì)數(shù)也是一種垃圾收集機(jī)制, 而且也是一種最直觀, 最簡單的垃圾收集技術(shù).當(dāng)python某個對象的引用計(jì)數(shù)降為 0 時, 說明沒有任何引用指向該對象, 該對象就成為要被回收的垃圾了.(如果出現(xiàn)循環(huán)引用的話, 引用計(jì)數(shù)機(jī)制就不再起作用了)
優(yōu)點(diǎn):簡單實(shí)時性,缺點(diǎn):維護(hù)引用計(jì)數(shù)消耗資源,且無法解決循環(huán)引用。
如果兩個對象的引用計(jì)數(shù)都為 1 , 但是僅僅存在他們之間的循環(huán)引用,那么這兩個對象都是需要被回收的, 也就是說 它們的引用計(jì)數(shù)雖然表現(xiàn)為非 0 , 但實(shí)際上有效的引用計(jì)數(shù)為 0 ,.所以先將循環(huán)引用摘掉, 就會得出這兩個對象的有效計(jì)數(shù).
標(biāo)記清除算法也有明顯的缺點(diǎn):清除非活動的對象前它必須順序掃描整個堆內(nèi)存,哪怕只剩下小部分活動對象也要掃描所有對象。
為了提高效率,有很多對象,清理了很多次他依然存在,可以認(rèn)為,這樣的對象不需要經(jīng)常回收,可以把它分到不同的集合,每個集合回收的時間間隔不同。簡單的說這就是python的分代回收。
具體來說,python中的垃圾分為1,2,3代,在1代里的對象每次回收都會去清理,當(dāng)清理后有引用的對象依然存在,此時他會進(jìn)入2代集合,同理2代集合清理的時候存在的對象會進(jìn)入3代集合。
每個集合的清理時間如何分配:會先清理1代垃圾,當(dāng)清理10次一代垃圾后會清理一次2代垃圾,當(dāng)清理10次2代垃圾后會清理3代垃圾。
在Python中,許多時候申請的內(nèi)存都是小塊的內(nèi)存,這些小塊內(nèi)存在申請后,很快又會被釋放,當(dāng)創(chuàng)建大量消耗小內(nèi)存的對象時,頻繁調(diào)用new/malloc會導(dǎo)致大量的內(nèi)存碎片,致使效率降低。
內(nèi)存池的概念就是預(yù)先在內(nèi)存中申請一定數(shù)量的,大小相等的內(nèi)存塊留作備用,當(dāng)有新的內(nèi)存需求時,就先從內(nèi)存池中分配內(nèi)存給這個需求,不夠了之后再申請新的內(nèi)存。這樣做最顯著的優(yōu)勢就是能夠減少內(nèi)存碎片,提升效率。
Python中有分為大內(nèi)存和小內(nèi)存:(256K為界限分大小內(nèi)存)
大小小于256kb時,pymalloc會在內(nèi)存池中申請內(nèi)存空間,當(dāng)大于256kb,則會直接執(zhí)行 new/malloc 的行為來申請新的內(nèi)存空間
在python中 -5到256之間的數(shù)據(jù),系統(tǒng)會默認(rèn)給每個數(shù)字分配一個內(nèi)存區(qū)域,其后有賦值時都會指向固定的已分配的內(nèi)存區(qū)域
在運(yùn)行py程序的時候,解釋器會專門分配一塊空白的內(nèi)存,用來存放純單詞字符組成的字符串(數(shù)字,字母,下劃線)
字符串賦值時,會先去查找要賦值的字符串是否已存在于內(nèi)存區(qū)域,已存在,則指向已存在的內(nèi)存,不存在,則會在大整數(shù)池中分配一塊內(nèi)存存放此字符串
論壇
活動
招聘
專題
打開CSDN APP
Copyright ? 1999-2020, CSDN.NET, All Rights Reserved
登錄
XCCS_澍
關(guān)注
Python 的內(nèi)存管理機(jī)制及調(diào)優(yōu)手段? 原創(chuàng)
2018-08-05 06:50:53
XCCS_澍
碼齡7年
關(guān)注
內(nèi)存管理機(jī)制:引用計(jì)數(shù)、垃圾回收、內(nèi)存池。
一、引用計(jì)數(shù):
引用計(jì)數(shù)是一種非常高效的內(nèi)存管理手段, 當(dāng)一個 Python 對象被引用時其引用計(jì)數(shù)增加 1, 當(dāng)其不再被一個變量引用時則計(jì)數(shù)減 1. 當(dāng)引用計(jì)數(shù)等于 0 時對象被刪除。
二、垃圾回收 :
1. 引用計(jì)數(shù)
引用計(jì)數(shù)也是一種垃圾收集機(jī)制,而且也是一種最直觀,最簡單的垃圾收集技術(shù)。當(dāng) Python 的某個對象的引用計(jì)數(shù)降為 0 時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了。比如某個新建對象,它被分配給某個引用,對象的引用計(jì)數(shù)變?yōu)?1。如果引用被刪除,對象的引用計(jì)數(shù)為 0,那么該對象就可以被垃圾回收。不過如果出現(xiàn)循環(huán)引用的話,引用計(jì)數(shù)機(jī)制就不再起有效的作用了
2. 標(biāo)記清除
如果兩個對象的引用計(jì)數(shù)都為 1,但是僅僅存在他們之間的循環(huán)引用,那么這兩個對象都是需要被回收的,也就是說,它們的引用計(jì)數(shù)雖然表現(xiàn)為非 0,但實(shí)際上有效的引用計(jì)數(shù)為 0。所以先將循環(huán)引用摘掉,就會得出這兩個對象的有效計(jì)數(shù)。
3. 分代回收
從前面“標(biāo)記-清除”這樣的垃圾收集機(jī)制來看,這種垃圾收集機(jī)制所帶來的額外操作實(shí)際上與系統(tǒng)中總的內(nèi)存塊的數(shù)量是相關(guān)的,當(dāng)需要回收的內(nèi)存塊越多時,垃圾檢測帶來的額外操作就越多,而垃圾回收帶來的額外操作就越少;反之,當(dāng)需回收的內(nèi)存塊越少時,垃圾檢測就將比垃圾回收帶來更少的額外操作。
函數(shù)其實(shí)也就是封裝好的算法代碼,因?yàn)橐恍┏S煤瘮?shù)都經(jīng)過開發(fā)者,用戶的多次測試優(yōu)化,在python的開源環(huán)境下更是如此,所以大多時候比新手開發(fā)者自己寫的方法內(nèi)存性能都有提升,但針對不同的需求,自己寫新的算法可能更優(yōu),并不絕對
網(wǎng)頁名稱:python內(nèi)存函數(shù)調(diào)整,python的內(nèi)存機(jī)制
鏈接URL:http://chinadenli.net/article13/dseoods.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站策劃、響應(yīng)式網(wǎng)站、微信小程序、網(wǎng)站建設(shè)、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)