詳解Nginx中基本的內(nèi)存池初始化配置
ngx_cycle 的初始化
整個(gè)初始化過程中,最重要的就是全局變量 nginx_cycle 的初始化,很多變量都是在這個(gè)過程中初始化的
nginx_cycle 又是通過兩個(gè)局部變量 init_cycle 和 cycle 實(shí)現(xiàn)初始化的
事實(shí)上,日志初始化也可以算是對(duì) nginx_cyle 的初始化,因?yàn)樵诖a中接下來馬上要發(fā)生的就是一個(gè)賦值
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t)); init_cycle.log = log; ngx_cycle = &init_cycle; // 創(chuàng)建內(nèi)存池 1KB init_cycle.pool = ngx_create_pool(1024, log); if (init_cycle.pool == NULL) { return 1; } // 保存調(diào)用參數(shù)到全局變量,init_cycle 只用于提供 log 參數(shù) if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) { return 1; } // 保存配置文件路徑、程序運(yùn)行路徑、調(diào)用參數(shù)到 init_cycle if (ngx_process_options(&init_cycle) != NGX_OK) { return 1; } // 獲取操作系統(tǒng)信息、CPU信息、最大連接數(shù)、是否支持非阻塞連接等 if (ngx_os_init(log) != NGX_OK) { return 1; } /* * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() */ // 對(duì)齊校驗(yàn)表 if (ngx_crc32_table_init() != NGX_OK) { return 1; } // 獲取所有繼承連接fd的相關(guān)信息 if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) { return 1; }
內(nèi)存池
nginx 是通過資源集中管理的方式管理資源的,即打開所有即將要用的資源,以備隨時(shí)取用,無論是文件還是內(nèi)存
這樣做的好處是避免了每次創(chuàng)建、打開資源造成的性能消耗
因此,便有了內(nèi)存池模塊,用來集中申請(qǐng)內(nèi)存資源并進(jìn)行內(nèi)存資源的管理和分配
內(nèi)存池結(jié)構(gòu):
// struct ngx_pool_data_t // 內(nèi)存池?cái)?shù)據(jù)塊結(jié)構(gòu) {{{ typedef struct { u_char *last; // 當(dāng)前內(nèi)存分配的結(jié)束位置 u_char *end; // 內(nèi)存池的結(jié)束位置 ngx_pool_t *next; // 下一內(nèi)存池 ngx_uint_t failed; // 內(nèi)存分配失敗計(jì)數(shù) } ngx_pool_data_t; // }}} // struct ngx_pool_s // 內(nèi)存池結(jié)構(gòu) {{{ struct ngx_pool_s { ngx_pool_data_t d; // 內(nèi)存池?cái)?shù)據(jù)塊 size_t max; // 待分配內(nèi)存大小 ngx_pool_t *current; // 指向當(dāng)前內(nèi)存池起始位置 ngx_chain_t *chain; ngx_pool_large_t *large; // 指向大塊內(nèi)存分配 ngx_pool_cleanup_t *cleanup; // 析構(gòu)函數(shù) ngx_log_t *log; // 內(nèi)存分配相關(guān)的log }; // }}}
在這個(gè)函數(shù)中,使用了一個(gè)封裝好的函數(shù) ngx_memalign,這個(gè)函數(shù)是對(duì)系統(tǒng)中按照數(shù)據(jù)對(duì)齊方式分配內(nèi)存的函數(shù)的封裝,在不同的系統(tǒng)中實(shí)現(xiàn)方式不同,通過宏定義,實(shí)現(xiàn)了操作系統(tǒng)的適配,這是一個(gè)很漂亮的技巧
#if (NGX_HAVE_POSIX_MEMALIGN) // void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log) // 用數(shù)據(jù)對(duì)齊的方式進(jìn)行內(nèi)存分配 {{{ void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log) { void *p; int err; // size 單位是 byte 而不是 bit err = posix_memalign(&p, alignment, 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) // 用數(shù)據(jù)對(duì)齊的方式進(jìn)行內(nèi)存分配 {{{ void * ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
所有有關(guān)內(nèi)存分配的系統(tǒng)調(diào)用函數(shù)的封裝都定義在 ngx_alloc.c 文件中
這里用到了 posix_memalign 系統(tǒng)調(diào)用,使用這個(gè)系統(tǒng)調(diào)用分配出來的內(nèi)存是默認(rèn)按照第二個(gè)參數(shù)的大小對(duì)齊的,這樣在進(jìn)行數(shù)據(jù)讀寫的時(shí)候,CPU可以周期地對(duì)整塊數(shù)據(jù)進(jìn)行讀寫,很大程度的節(jié)省了CPU時(shí)間
這個(gè)系統(tǒng)調(diào)用所分配的內(nèi)存也是存在于堆內(nèi)存中的,可以使用 free 函數(shù)進(jìn)行釋放,不過 malloc 分配的內(nèi)存默認(rèn)也是對(duì)齊的,它相對(duì)于 malloc 的優(yōu)勢(shì)僅僅在于可以指定默認(rèn)對(duì)齊大小。
函數(shù)完成了內(nèi)存池的初步分配,執(zhí)行后 pool 取值:
$23 = (ngx_pool_t *) 0x80fe9f0 (gdb) p *init_cycle.pool $24 = { d = { last = 0x80fea18, end = 0x80fedf0, next = 0x0, failed = 0 }, max = 984, current = 0x80fe9f0, chain = 0x0, large = 0x0, cleanup = 0x0, log = 0x80e3020 <ngx_log> }
如下圖所示:
相關(guān)文章
Nginx在MAC上的安裝、啟動(dòng)、重啟和關(guān)閉
這篇文章主要介紹了Nginx在MAC上的安裝、啟動(dòng)、重啟和關(guān)閉的相關(guān)資料,需要的朋友可以參考下2018-03-03Nginx中IF語句實(shí)現(xiàn)數(shù)學(xué)比較功能
這篇文章主要介紹了Nginx中IF語句實(shí)現(xiàn)數(shù)學(xué)比較功能,即在Nginx中用if判斷數(shù)字大小,類似編程語言中的邏輯比較,需要的朋友可以參考下2015-02-02Nginx Rewrite規(guī)則與使用介紹和技巧實(shí)例
這篇文章主要介紹了Nginx Rewrite規(guī)則與使用介紹和技巧實(shí)例,本文講解了正則表達(dá)式匹配、文件及目錄匹配、flag標(biāo)記、Nginx Rewrite相關(guān)指令等內(nèi)容,需要的朋友可以參考下2015-01-01nginx 不同的訪問路徑對(duì)應(yīng)項(xiàng)目不同的目錄的實(shí)現(xiàn)方法
要在 Nginx 中配置不同的訪問路徑對(duì)應(yīng)不同的項(xiàng)目目錄,可以使用 Nginx 的?location?指令來實(shí)現(xiàn),本文主要介紹了nginx不同的訪問路徑對(duì)應(yīng)項(xiàng)目不同的目錄的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09安裝Windows版nginx及部署前端代碼并解決刷新出現(xiàn)404問題
這篇文章主要給大家介紹了關(guān)于安裝Windows版nginx及部署前端代碼解決刷新出現(xiàn)404問題的相關(guān)資料,使用nginx部署前端項(xiàng)目是一篇非常詳細(xì)的教程,旨在幫助初學(xué)者使用Nginx來部署前端項(xiàng)目,需要的朋友可以參考下2023-12-12Nginx配置WebSocket反向代理的實(shí)現(xiàn)示例
本文主要介紹了Nginx配置WebSocket反向代理的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08