Nginx源碼閱讀筆記-內存池的設計

nginx的內存池設計的比較簡單了,一個內存池中分爲兩個部分:nginx

  • 超過max大小的內存分配,走大塊內存分配,這部份內存管理由ngx_pool_large_t結構體負責。
  • 不然就是在ngx_pool_t遍歷符合要求的ngx_pool_t結構體,找到符合要求大小的pool直接返回,不然就申請一塊新的內存pool。

nginx中全部請求都單獨對應一個內存池,在這個請求的過程當中,全部涉及到內存分配的地方,都到該請求相關的內存池中處理,而中間不會去釋放回收內存,內存池的生命週期與請求同樣,請求完畢則直接回收內存。這樣的好處在於:統一分配和統一釋放,下降了內存泄露問題的出現。數據結構

ngx_pool_data_t

先來看結構體ngx_pool_data_t,它存儲每一個ngx_pool_t結構體的meta元數據:架構

  • u_char *last:指向分配空間的可用空間。
  • u_char *end:指向分配空間的最後位置。
  • ngx_pool_t *next:指向下一個ngx_pool_t指針。
  • ngx_uint_t failed:存儲本ngx_pool_t結構體分配失敗次數。

failed成員的引入是爲了不某個pool雖然還有可用的空間,可是因爲空間很小了因此常常性的分配空間失敗,當累計失敗的次數達到某個閾值時,下一次再次查找內存就直接跳過這個pool,而去尋找內存池鏈表中的下一個pool。在此我向你們推薦一個架構學習交流裙。交流學習裙號:687810532,裏面會分享一些資深架構師錄製的視頻錄像學習

ngx_pool_large_t

ngx_pool_large_t結構體用於保存大內存塊,這一塊就比較簡單粗暴了,直接分配一塊大內存來使用。另外,多個大內存塊之間也是以鏈表形式來組織數據。ui

// 管理超大空間的結構體
struct ngx_pool_large_s {
  // 指向下一個指針
  ngx_pool_large_t     *next;
  // 直接指向內存區域的指針
  void                 *alloc;
};

ngx_pool_t

再來看ngx_pool_t結構體,該數據結構用於表示一個內存池,內存池內部以鏈表形式來組織數據。以下圖:spa

須要說明的是:設計

  • 內存池內部以鏈表形式組織起來,完成這個工做的就是前面的ngx_pool_data_t的next成員。
  • current指針,用於表示當前該內存池在使用的pool指針。除了內存池鏈表的頭結點以外,內存池鏈表其餘節點的該指針無效。之因此須要這個指針,就是前面提到的,在某個內存池屢次失效的狀況下,下一次直接跳過該內存池查找空間,current指針保存當前在內存池鏈表的哪個內存池上面查找空間。

有了以上數據結構的瞭解,從內存池分配內存的流程就很簡單了:指針

相關文章
相關標籤/搜索