一、內(nèi)存池概述
內(nèi)存池是在真正使用內(nèi)存之前,預(yù)先申請分配一定數(shù)量的、大小相等(一般情況下)的內(nèi)存塊留作備用。當(dāng)有新的內(nèi)存需求時,就從內(nèi)存池中分出一部分內(nèi)存塊,若內(nèi)存塊不夠再繼續(xù)申請新的內(nèi)存。
內(nèi)存池的好處有減少向系統(tǒng)申請和釋放內(nèi)存的時間開銷,解決內(nèi)存頻繁分配產(chǎn)生的碎片,提示程序性能,減少程序員在編寫代碼中對內(nèi)存的關(guān)注等
一些常見的內(nèi)存池實現(xiàn)方案有STL中的內(nèi)存分配區(qū),boost中的object_pool,nginx中的ngx_pool_t,google的開源項目TCMalloc等
二、nginx內(nèi)存池綜述
nginx為tcp連接,http請求,模塊都分配了一個內(nèi)存池,在結(jié)束的時候會摧毀整個內(nèi)存池,把分配的內(nèi)存一次性歸還給操作系統(tǒng)。
在分配的內(nèi)存上,nginx有小塊內(nèi)存和大塊內(nèi)存的概念,小塊內(nèi)存 nginx在分配的時候會嘗試在當(dāng)前的內(nèi)存池節(jié)點中分配,而大塊內(nèi)存會調(diào)用系統(tǒng)函數(shù)malloc向操作系統(tǒng)申請
在釋放內(nèi)存的時候,nginx沒有專門提供針對釋放小塊內(nèi)存的函數(shù),小塊內(nèi)存會在ngx_destory_pool 和 ngx_reset_pool的時候一并釋放
區(qū)分小塊內(nèi)存和大塊內(nèi)存的原因有2個,
1、針對大塊內(nèi)存 如果它的生命周期遠(yuǎn)遠(yuǎn)短于所屬的內(nèi)存池,那么提供一個單獨的釋放函數(shù)是十分有意義的,但不區(qū)分大塊內(nèi)存和小塊內(nèi)存,針對大的內(nèi)存塊 便會無法提前釋放了
2、大塊內(nèi)存與小塊內(nèi)存的界限是一頁內(nèi)存(p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL,宏NGX_MAX_ALLOC_FROM_POOL通過調(diào)用getpagesize活動),大于一頁的內(nèi)存在物理上不一定是連續(xù)的
所以如果分配的內(nèi)存大于一頁的話,從內(nèi)存