資源簡介
通過把nginx slab的精簡,把需要的頭文件單獨整理出來,增加了main方法,可以單獨運行,代碼包含了大量的中文注釋,方便了了解和學習slab的運行機制
int main(int argc, char **argv) {
ngx_log_t log;
ngx_shm_t shm;
ngx_slab_pool_t *shpool;
char *ssl_session[10];
int n;
ngx_pid = ngx_getpid();
memset(&log;, 0, sizeof(ngx_log_t));
memset(&shm;, 0, sizeof(ngx_shm_t));
shm.size = 512000;
ngx_pagesize_shift = 0;
ngx_pagesize = getpagesize();
for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */
}
printf("--%d\n", 1 << ngx_pagesize_shift);
if (ngx_shm_alloc(&shm;) != NGX_OK) {
return 1;
}
if (ngx_init_zone_pool(&log;, &shm;)) {
return 1;
}
shpool = (ngx_slab_pool_t *) shm.addr;
ssl_session[0] = (char *) ngx_slab_alloc_locked(shpool, 12);
ssl_session[0] = (char *) ngx_slab_calloc(shpool, 56);
ssl_session[1] = (char *) ngx_slab_alloc_locked(shpool, 14);
ssl_session[2] = (char *) ngx_slab_alloc_locked(shpool, 11);
ngx_slab_free(shpool, ssl_session[2]);
ngx_slab_free(shpool, ssl_session[0]);
ssl_session[2] = (char *) ngx_slab_alloc_locked(shpool, 65);
return 0;
}
nginx的slab的內存管理方式,這種方式的內存管理在nginx中,主要是與nginx
的共享內存協同使用的。nginx的slab管理與linux的slab管理相同的地方在于均是利用了內存
的緩存與對齊機制,slab內存管理中一些設計相當巧妙的地方,也有一些地方個人感覺設計
不是很完美,或許是作為nginx設計綜合考慮的結果。
nginx slab實現中的一大特色就是大量的位操作,這部分操作很多是與slot分級數組相關的。
為方便描述下面做一些說明:
1.將整個slab的管理結構稱slab pool.
2.將slab pool前部的ngx_slab_pool_t結構稱slab header.
3.將管理內存分級的ngx_slab_page_t結構稱slot分級數組.
4.將管理page頁使用的ngx_slab_page_t結構稱slab page管理結構.
5.將具體page頁的存放位置稱pages數組.
6.將把page分成的各個小塊稱為chunk.
7.將標記chunk使用的位圖結構稱為bitmap.
代碼片段和文件信息
/*
?*?Copyright?(C)?Igor?Sysoev
?*?Copyright?(C)?Nginx?Inc.
?*/
#include?
#include?
//getconf?PAGE_SIZE?命令可以查看
ngx_uint_t??ngx_pagesize;//見ngx_os_init??返回一個分頁的大小,單位為字節(Byte)。該值為系統的分頁大小,不一定會和硬件分頁大小相同。
//ngx_pagesize為4M,ngx_pagesize_shift應該為12
ngx_uint_t??ngx_pagesize_shift;?//ngx_pagesize進行移位的次數,見for?(n?=?ngx_pagesize;?n?>>=?1;?ngx_pagesize_shift++)?{?/*?void?*/?}
/*
如果能知道CPU?cache行的大小,那么就可以有針對性地設置內存的對齊值,這樣可以提高程序的效率。
Nginx有分配內存池的接口,Nginx會將內存池邊界對齊到?CPU?cache行大小??32位平臺,ngx_cacheline_size=32
*/
ngx_uint_t??ngx_cacheline_size;//32位平臺,ngx_cacheline_size=32
void?*
ngx_alloc(size_t?size?ngx_log_t?*log)
{
????void??*p;
????p?=?malloc(size);
????if?(p?==?NULL)?{
????????ngx_log_error(NGX_LOG_EMERG?log?ngx_errno
??????????????????????“malloc(%uz)?failed“?size);
????}
???//?ngx_log_debug2(NGX_LOG_DEBUG_ALLOC?log?0?“malloc:?%p:%uz“?p?size);
????return?p;
}
void?*
ngx_calloc(size_t?size?ngx_log_t?*log)
{
????void??*p;
????p?=?ngx_alloc(size?log);
????if?(p)?{
????????ngx_memzero(p?size);
????}
????return?p;
}
#if?(NGX_HAVE_POSIX_MEMALIGN)
void?*
ngx_memalign(size_t?alignment?size_t?size?ngx_log_t?*log)
{
????void??*p;
????int????err;
????err?=?posix_memalign(&p?alignment?size);//?分配一塊?size?大小的內存
????if?(err)?{
????????ngx_log_error(NGX_LOG_EMERG?log?err
??????????????????????“posix_memalign(%uz?%uz)?failed“?alignment?size);
????????p?=?NULL;
????}
????//ngx_log_debug3(NGX_LOG_DEBUG_ALLOC?log?0“posix_memalign:?%p:%uz?@%uz“?p?size?alignment);
????return?p;
}
#elif?(NGX_HAVE_MEMALIGN)
void?*
ngx_memalign(size_t?alignment?size_t?size?ngx_log_t?*log)
{
????void??*p;
????p?=?memalign(alignment?size);
????if?(p?==?NULL)?{
????????ngx_log_error(NGX_LOG_EMERG?log?ngx_errno
??????????????????????“memalign(%uz?%uz)?failed“?alignment?size);
????}
????//ngx_log_debug3(NGX_LOG_DEBUG_ALLOC?log?0?????????“memalign:?%p:%uz?@%uz“?p?size?alignment);
????return?p;
}
#endif
評論
共有 條評論