Ngnix內存池——高并發實現高效內存管理

目錄

一、高并發下傳統方式的弊端

1、常用的內存操作函數

2、弊端一

3、弊端二

4、弊端三

5、弊端四

二、弊端解決之道

1、內存管理維度分析

2、內存管理組件選型

三、高并發內存管理最佳實踐

1、內存池技術

2、內存池如何解決弊端

3、高并發內存池如何實現

四、高效內存池設計與實現

1、內存池的實現思路

2、Nginx內存池結構圖

3、關鍵數據結構

4、ngx_pool_t結構示意圖(大希奧未1024的池)

?5、Nginx內存池基本操作


一、高并發下傳統方式的弊端

1、常用的內存操作函數

void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);

malloc? 在內存的動態存儲區中分配一塊長度為size字節的連續區域返回該區域的首地址.

calloc? 與malloc相似,參數size為申請地址的單位元素長度,nmemb為元素個數,即在內存中申請nmemb*size字節大小的連續地址空間.內存會初始化0

realloc? 給一個已經分配了地址的指針重新分配空間,參數ptr為原有的空間地址,newsize是重新申請的地址長度.ptr 若為NULL,它就等同于 malloc.

2、弊端一

高并發時較小內存塊使用導致系統調用頻繁,降低了系統的執行效率。(系統調用不了解的,觀看我博客里系統調用的一文)。

3、弊端二

頻繁使用時增加了系統內存的碎片,降低內存使用效率

內部碎片 已經被分配出去(能明確指出屬于哪個進程)卻不能被利用的內存空間;

產生根源1.內存分配必須起始于可被 4、8 或 16 整除(視處理器體系結構而定)的地址

????????????????? 2.MMU的分頁機制的限制

處理器

頁大小

分頁的級別

虛擬地址分級

x86

4KB

2

10+10+12

x86(extended)

4KB

1

10+22

x86(PAE)

4KB

3

2+9+9+12

x86-64

4KB

4

9+9+9+9+12

4、弊端三

沒有垃圾回收機制,容易造成內存泄漏,導致內存枯竭

情形一:
void log_error(char *reason) 
{ char *p1; p1 = malloc(100); sprintf(p1,"The f1 error occurred because of '%s'.", reason); log(p1); 
}情形二:  
int getkey(char *filename) 
{ FILE *fp; int key; fp = fopen(filename, "r");fscanf(fp, "%d", &key); //fclose(fp);return key; 
}

5、弊端四

內存分配與釋放的邏輯在程序中相隔較遠時,降低程序的穩定性

例如:程序1調用程序2,誤認為傳參過來的是指針,用完后,進行了釋放

//程序1
ret get_stu_info(Student  * _stu) 
{ char  * name= NULL; name = getName(_stu->no);//處理邏輯if(name) {free(name);name = NULL;}
}
//程序2
char stu_name[MAX];char * getName(int stu_no)
{//查找相應的學號并賦值給 stu_namesnprintf(stu_name,MAX,“%s”,name);return stu_name;
}

二、弊端解決之道

1、內存管理維度分析

2、內存管理組件選型

PtMalloc

(glibc 自帶)

TcMalloc

JeMalloc

概念

Glibc 自帶

Google 開源

Jason Evans

(FreeBSD著名開發人員)

性能

(一次malloc/free 操作)

300ns

50ns

<=50ns

弊端

鎖機制降低性能,容易導致內存碎片

1%左右的額外內存開銷

2%左右的額外內存開銷

優點

傳統,穩定

線程本地緩存,多線程分配效率高

線程本地緩存,多核多線程分配效率相當高

使用方式

Glibc 編譯

動態鏈接庫

動態鏈接庫

誰在用

較普遍

safari、chrome等

facebook、firefox

適用場景

除特別追求高效內存分配以外的

多線程下高效內存分配

多線程下高效內存分配

三、高并發內存管理最佳實踐

1、內存池技術

什么是內存池技術?

在真正使用內存之前,先申請分配一定數量的、大小相等(一般情況下)的內存塊留作備用。當有新的內存需求時,就從內存池中分出一部分內存塊,若內存塊不夠再繼續申請新的內存,統一對程序所使用的內存進行統一的分配和回收。這樣做的一個顯著優點是,使得內存分配效率得到很大的提升。

2、內存池如何解決弊端

(1)、高并發時系統調用頻繁,降低了系統的執行效率

????????內存池提前預先分配大塊內存,統一釋放,極大的減少了malloc 和 free 等函數的調用。

(2)、頻繁使用時增加了系統內存的碎片,降低內存使用效率

????????內存池每次請求分配大小適度的內存塊,避免了碎片的產生

(3)、沒有垃圾回收機制,容易造成內存泄漏

????????在生命周期結束后統一釋放內存,完全避免了內存泄露的產生

(4)、內存分配與釋放的邏輯在程序中相隔較遠時,降低程序的穩定性

????????在生命周期結束后統一釋放內存,避免重復釋放指針或釋放空指針等情況

3、高并發內存池如何實現

高并發(High Concurrency是互聯網分布式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時并行處理很多請求。

高并發特點

(1)、響應時間短

(2)、吞吐量大

(4)、每秒響應請求數 QPS

(5)、并發用戶數高:

內存池設計考慮

設計邏輯應該盡量簡單,避免不同請求之間互相影響,盡量降低不同模塊之間的耦合

內存池生存時間應該盡可能短,與請求或者連接具有相同的周期,減少碎片堆積和內存泄漏

四、高效內存池設計與實現

1、內存池的實現思路

(1)、對于每個請求或者連接都會建立相應的內存池,建立好內存池之后,我們可以直接從內存池中申請所需要的內存,不用去管內存的釋放,當內存池使用完成之后一次性銷毀內存池。

(2)、區分大小內存塊的申請和釋放,大于池尺寸的定義為大內存塊,使用單獨的大內存塊鏈表保存,即時分配和釋放;小于等于池尺寸的定義為小內存塊,直接從預先分配的內存塊中提取,不夠就擴充池中的內存,在生命周期內對小塊內存不做釋放,直到最后統一銷毀。

2、Nginx內存池結構圖

3、關鍵數據結構

typedef struct 
{u_char               *last;         // 保存當前數據塊中內存分配指針的當前位置u_char               *end;         // 保存內存塊的結束位置ngx_pool_t           *next;      // 內存池由多塊內存塊組成,指向下一個數據塊的位置ngx_uint_t            failed;      // 當前數據塊內存不足引起分配失敗的次數
} ngx_pool_data_t;struct ngx_pool_s 
{ngx_pool_data_t       d;        // 內存池當前的數據區指針的結構體size_t                max;      // 當前數據塊最大可分配的內存大小(Bytes)ngx_pool_t           *current;  // 當前正在使用的數據塊的指針ngx_pool_large_t     *large;    // pool 中指向大數據塊的指針(大數據快是指 size > max 的數據塊)
};

4、ngx_pool_t結構示意圖(大希奧未1024的池)



5、Nginx內存池基本操作

內存池創建、銷毀和重置:

操作

函數

創建內存池

ngx_pool_t *? ngx_create_pool(size_t size);

銷毀內存池

void ngx_destroy_pool(ngx_pool_t *pool);

重置內存池

void ngx_reset_pool(ngx_pool_t *pool);

內存池申請、釋放和回收操作:

操作

函數

內存申請(對齊)

void *? ngx_palloc(ngx_pool_t *pool, size_t size);

內存申請(不對齊)

void *? ngx_pnalloc(ngx_pool_t *pool, size_t size);

內存申請(對齊并初始化)

void *? ngx_pcalloc(ngx_pool_t *pool, size_t size);

內存清除

ngx_int_t? ngx_pfree(ngx_pool_t *pool, void *p);

內存池申請、釋放和回收操作:

操作

函數

內存申請(對齊)

void *? ngx_palloc(ngx_pool_t *pool, size_t size);

內存申請(不對齊)

void *? ngx_pnalloc(ngx_pool_t *pool, size_t size);

內存申請(對齊并初始化)

void *? ngx_pcalloc(ngx_pool_t *pool, size_t size);

內存清除

ngx_int_t? ngx_pfree(ngx_pool_t *pool, void *p);

源碼代碼詳細見上傳資源

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/36881.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/36881.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/36881.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FC-Planner: 一個基于骨架引導的快速覆蓋復雜3D場景的規劃框架方案實現與難點講解

FC-Planner方案實現細節與難點講解 1. 骨架提取 骨架提取是FC-Planner的核心模塊之一,其目的是從輸入的點云數據中提取出場景的骨架結構。這一步的關鍵是如何準確高效地計算每個點的ROSA點。 1.1 ROSA點計算 ROSA點的計算涉及到兩個優化問題: ROSA點方向 v p v_p vp?的優化…

《數字圖像處理與機器視覺》案例二(基于邊緣檢測和數學形態學焊縫圖像處理)

一、前言 焊縫是評價焊接質量的重要標志&#xff0c;人工檢測方法存在檢測標準不統一&#xff0c;檢測精度低&#xff0c;焊縫視覺檢測技術作為一種重要的質量檢測方法&#xff0c;正逐漸在各行各業中嶄露頭角。把焊縫準確的從焊接工件中準確分割出來是焊縫評價的關鍵一步&…

linux上git的使用

目錄 1.測試是否安裝有git 2.下載項目到本地 3.三板斧 1.將代碼放在創建的目錄中 2.提交改動到本地 3.提交代碼到遠端 4.注意點 以及補充內容 1.測試是否安裝有git 如果輸入git --help 會顯示下面一大串那么就是已經安裝&#xff0c;否則需要自行手動安裝 yum install g…

聚焦從業人員疏散逃生避險意識能力提升,推動生產經營單位每年至少組織開展(疏散逃生演練,讓全體從業人員熟知逃生通道、安全出口及應急處置要求,形成常態化機制。

聚焦從業人員疏散逃生避險意識能力提升&#xff0c;推動生產經營單位每年至少組織開展(疏散逃生演練&#xff0c;讓全體從業人員熟知逃生通道、安全出口及應急處置要求&#xff0c;形成常態化機制。完整試題答案查看 A.三次B.兩次C.一次 綜合運用“四不兩直”、明察暗訪、 ()、…

潔盟超聲波清洗機怎么樣?橫向測評希亦、潔盟、蘇泊爾超聲波清洗機誰是實力派

生活中大多數人戴眼鏡&#xff0c;但是很多人都不注意眼鏡的保養&#xff0c;導致鏡片越來越模糊&#xff0c;從而引發多邊的狀況發生&#xff0c;比如長久戴模糊不清的眼鏡&#xff0c;視力會受到影響隨之下降。甚至是眼鏡長期不清洗&#xff0c;上面的灰塵、細菌會影響眼部健…

彩虹PLM系統在航空航天業的應用與實踐

彩虹PLM系統在航空航天業的應用與實踐 彩虹PLM系統作為航空航天業的卓越解決方案&#xff0c;已經在眾多企業中得到了廣泛的應用和實踐。該系統通過其獨特的功能和優勢&#xff0c;為航空航天企業帶來了顯著的管理效益和市場競爭力提升。 彩虹PLM系統 在應用方面&#xff0c;彩…

這樣解釋 TCP_IP 真的很好理解

想象一下&#xff0c;你住在一個大城市里&#xff0c;這個城市就是你的計算機網絡世界。在這個城市中&#xff0c;有許多房子&#xff08;代表不同的計算機&#xff09;&#xff0c;這些房子之間由各種道路和交通設施連接起來&#xff08;代表網絡的物理連接&#xff09;。 現在…

1.2 離散LTI系統的時域分析

目錄 離散系統的定義 離散LTI系統的時域描述h[k] 離散系統的分類 線性與非線性系統 時變與非時變系統 因果與非因果系統 穩定與不穩定系統 滑動平均系統 LTI——Linear and Time-invariant System 線性時不變系統 離散系統的定義 離散LTI系統的時域描述h[k] 離…

【java12】java12新特性之File的mismatch方法

Java12引入了一個新的方法 mismatch&#xff0c;它屬于java.nio.file.Files類。此方法用于比較兩個文件的內容&#xff0c;并返回第一個不匹配字節的位置。如果兩個文件完全相同&#xff0c;則返回-1。 Files.mismatch 方法聲明 public static long mismatch(Path path1, Pat…

【并發編程】2-Synchronized

基本概念 線程安全問題三個要素&#xff1a;多線程、共享資源、非原子性操作&#xff1b;產生的根本原因&#xff1a;多條線程同時對一個共享資源進行非原子性操作&#xff1b;Synchronized解決線程安全問題的方式&#xff1a;通過互斥鎖將多線程的并行執行變為單線程串行執行…

昇思25天學習打卡營第4天|數據集Dataset

數據集 Dataset 介紹 之前說過&#xff0c;MindSpore是基于Pipeline&#xff0c;通過Dataset和Transformer進行數據處理。Dataset在其中是用來加載原始數據的。mindSpore提供了數據集加載接口&#xff0c;可以加載文本、圖像、音頻等&#xff0c;同時也可以自定義加載接口。此…

【UE開發】游戲庫存UI系統Demo

1.項目介紹 1.描述&#xff1a;一種用于存儲記錄玩家物品的游戲內可視化操作系統。 2.演示&#xff1a;https://www.bilibili.com/video/BV1f53neVEfW/?vd_source50dea901fd12253f417c48b937975b0d 3.大綱&#xff1a; 4.樣式&#xff1a; 2.W_Inventory_Main_01&#xff08;…

CORE Mobility Errorr的調試

在運行CORE tutorial 3中的mobility示例時&#xff0c;出現如下錯誤&#xff1a; 當看到這個問題的時候&#xff0c;并沒有仔細去分析日志和現象&#xff0c;在core-daemon的進程打印界面只看了一下最后的出錯堆棧&#xff1a; 2024-06-27 10:43:48,614 - ERROR - _server:_ca…

MySQL8 新特性——公用表表達式用法 with t1 as (select * from user)

MySQL8 新特性——公用表表達式用法_mysql ctes-CSDN博客 1.普通公用表表達式 MySQL8 新特性——公用表表達式用法 在MySQL 8.0及更高版本中&#xff0c;引入了公用表表達式&#xff08;Common Table Expressions&#xff0c;CTEs&#xff09;&#xff0c;它是一種方便且可重…

docker部署vue項目

1.下載docker desktop軟件 Docker Desktop啟動的時候&#xff0c;有可能彈框提示"WSL2 installations is incomplete"&#xff0c;這是您的系統中沒有安裝WSL2內核的原因&#xff0c;打開【https://aka.ms/wsl2kernel ,在打開的頁面中有一個Linux內核更新包"鏈…

【python011】經緯度點位可視化html生成(有效方案)

1.熟悉、梳理、總結項目研發實戰中的Python開發日常使用中的問題、知識點等&#xff0c;如獲取省市等邊界區域經緯度進行可視化&#xff0c;從而輔助判斷、決策。 2.歡迎點贊、關注、批評、指正&#xff0c;互三走起來&#xff0c;小手動起來&#xff01; 3.歡迎點贊、關注、批…

Android InputReader 輸入事件處理流程

Android系統輸入事件產生的底層主要是輸入子系統&#xff0c;Android 中的輸入設備有很多&#xff0c;例如屏幕&#xff0c;鼠標&#xff0c;鍵盤等都是輸入設備&#xff0c;對于應用開發者&#xff0c;接觸最多的也就是屏幕了。 1. 當輸入設備可用時&#xff0c;Linux會在 /de…

tensorRT的安裝

在這個網址找到適合自己的版本&#xff0c;尤其是找到合適的cuda版本&#xff1a; https://pypi.nvidia.com/ 然后直接pip 安裝&#xff1a; 比如&#xff1a; pip install https://pypi.nvidia.com/tensorrt-cu11/tensorrt-cu11-10.1.0.tar.gz 也可以&#xff1a; wget http…

【MotionCap】SLAHMR 在 Colab 的demo運行筆記

【MotionCap】SLAHMR slahmr將人類和相機運動與野外視頻分離 CVPR 2023跳至主要內容 SLAHMR (supports 4D Humans).ipynb SLAHMR (supports 4D Humans).ipynb_筆記本已移除星標Google Colab demo for: SLAHMR - Simultaneous Localization And Human Mesh Recovery @inproc…

STM32將外部SDRAM空間作為系統堆(Heap)空間

概述 stm32可以外擴很大的sram&#xff0c;常見外部sram的初始化函數一般是c語言寫的&#xff0c;默認寫在main函數里面。stm32初始化首先進入匯編代碼startup_stm32f429xx.s&#xff0c;在匯編代碼中Reset_Handler&#xff08;復位中斷服務程序&#xff09;里面先調用了Syste…