Python中的内存管理机制
?
?
python引用了一個(gè)內(nèi)存池(memory pool)機(jī)制,即pymalloc機(jī)制,用于管理對(duì)小塊內(nèi)存的申請(qǐng)和釋放
-
1.介紹
python和其他高級(jí)語(yǔ)言一樣,會(huì)進(jìn)行自動(dòng)的內(nèi)存管理。它使用引用計(jì)數(shù)機(jī)制檢測(cè)為對(duì)象分配的內(nèi)存是否可以被釋放。然后,在Python中內(nèi)存永遠(yuǎn)不會(huì)返還給操作系統(tǒng),Python會(huì)持有這些內(nèi)存并在需要時(shí)重新使用它們。在很多場(chǎng)景下,這個(gè)特性可以減少內(nèi)存申請(qǐng)和釋放所帶來(lái)的性能損耗;但對(duì)于需要長(zhǎng)時(shí)間運(yùn)行的Python進(jìn)程來(lái)講,Python將會(huì)占用大量的內(nèi)存。如果進(jìn)程使用內(nèi)存的峰值遠(yuǎn)大于平均值,這將會(huì)造成內(nèi)存的浪費(fèi)從而影響本進(jìn)程甚至是系統(tǒng)中其他進(jìn)程的性能。
?
-
2.Pymalloc
Python使用pymalloc管理內(nèi)存。在Python中,會(huì)頻繁的創(chuàng)建和刪除很多小對(duì)象,如果這些對(duì)象的內(nèi)存申請(qǐng)和釋放都使用malloc()和free(),將會(huì)帶來(lái)嚴(yán)重的性能問(wèn)題。因此,pymalloc分配一系列256KB內(nèi)存塊,稱之為arena。每個(gè)arena分割為4KB大小的內(nèi)存池Pool,每個(gè)Pool在切分為固定大小的Block。在內(nèi)存分配時(shí),分配給進(jìn)程的就是這些Blocks。
-
3.內(nèi)存分配
上圖中展示了一個(gè)usedpool數(shù)組,此數(shù)組按內(nèi)存大小組織,每個(gè)大小對(duì)應(yīng)一個(gè)pool鏈表,每個(gè)pool鏈表中有多個(gè)空閑的Block。在分配內(nèi)存時(shí),Pymalloc先判斷是否存在要申請(qǐng)的大小的pool,如果存在的話,直接從pool中獲取一個(gè)free Block返回給應(yīng)用程序,這個(gè)過(guò)程非常迅速。如果分配完這個(gè)Block后此pool變?yōu)橐粋€(gè)空pool,則將這個(gè)Pool從鏈表中移除。
如果在usedpool中找不到大小匹配的pool,需要在freepool中查找可用的pool。在找不到的情況下,首先會(huì)嘗試在最后一個(gè)arena中是否存在可用的內(nèi)存,如果有的話則分配一個(gè)非freepool使用;如果不存在這樣的arena,將會(huì)通過(guò)malloc()分配一個(gè)新的arena。在freepool中找到一個(gè)可用的Pool后,會(huì)將此Pool切分為固定大小的Pool并加入到userdpool中,并在其中分配一個(gè)Free Block應(yīng)用程序。
-
4.內(nèi)存釋放
在應(yīng)用程序要釋放一個(gè)Block時(shí),過(guò)程和分配的過(guò)程比較相似。首先會(huì)根據(jù)Block找到此Block所歸屬的ool,然后將此Block加入到Pool的Free Block列表中。如果Pool當(dāng)前是空的,還會(huì)將這個(gè)Pool加入到usedpool的鏈表中。如果在Block加入到Free Block后所有的Block都是Free的,會(huì)將此Pool從usedpool移動(dòng)到freepool中
上面的過(guò)程可以看到,內(nèi)存釋放的過(guò)程基本就是內(nèi)存申請(qǐng)的反過(guò)程,但唯一的區(qū)別是缺少了將freepool反換費(fèi)arena,并將arena通過(guò)free()返還給操作系統(tǒng)的步驟。
-
5.基本數(shù)據(jù)類型的內(nèi)存分配
Python中有一小部分的對(duì)象是不使用pymalloc進(jìn)程內(nèi)存分配的,主要是integer/float/list/dict。為了提升這些常用對(duì)象的內(nèi)存使用效率,這些對(duì)象是保存在單獨(dú)的列表中的。
Python通過(guò)malloc()為Integer/Floal兩種類型分配大約1KB大小的內(nèi)存塊列表,這些列表被當(dāng)做Integer/Float的數(shù)組使用,而不是使用Pymalloc的分配的8字節(jié)的整數(shù)倍大小的Block,以減少內(nèi)存消耗。在創(chuàng)建一個(gè)新的Integer/Float對(duì)象時(shí),字直接從這個(gè)內(nèi)存列表中獲取數(shù)據(jù),或是重新分配一塊新的Block;在釋放時(shí)對(duì)應(yīng)的Block重新加入到列表中。這些Block也是不會(huì)被返還給操作系統(tǒng)的。
Python為list/dict采用不同的策略,會(huì)最多保留80個(gè)空閑的list/dict,如果多余80個(gè),多出的會(huì)被釋放
轉(zhuǎn)載于:https://www.cnblogs.com/eric_yi/p/7327470.html
總結(jié)
以上是生活随笔為你收集整理的Python中的内存管理机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 惠普发布软件定义存储 助力提升虚拟化能力
- 下一篇: Symfony3实现刷新登录时间