日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NGINX原理 之 SLAB分配机制(转)

發布時間:2023/11/30 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NGINX原理 之 SLAB分配机制(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 引言

? 眾所周知,操作系統使用伙伴系統管理內存,不僅會造成大量的內存碎片,同時處理效率也較低下。SLAB是一種內存管理機制,其擁有較高的處理效率,同時也有效的避免內存碎片的產生,其核心思想是預分配。其按照SIZE對內存進行分類管理的,當申請一塊大小為SIZE的內存時,分配器就從SIZE集合中分配一個內存塊(BLOCK)出去,當釋放一個大小為SIZE的內存時,則將該內存塊放回到原有集合,而不是釋放給操作系統。當又要申請相同大小的內存時,可以復用之前被回收的內存塊(BLOCK),從而避免了內存碎片的產生。[注:因SLAB處理過程的細節較多,在此只是做一個原理上的講解]

?

2 總體結構

圖1 SLAB內存結構

?

3 處理流程

如圖1中所示:SLAB管理機制將內存大體上分為SLAB頭、SLOT數組、PAGES數組、可分配空間、被浪費空間等模塊進行分別管理,其中各模塊的功能和作用:
  • SLAB頭:包含SLAB管理的匯總信息,如最小分配單元(min_size)、最小分配單元對應的位移(min_shift)、頁數組地址(pages)、空閑頁鏈表(free)、可分配空間的起始地址(start)、內存塊結束地址(end)等等信息(如代碼1所示),在內存的管理過程中,內存的分配、回收、定位等等操作都依賴于這些數據。
  • SLOT數組:SLOT數組各成員分別負責固定大小的內存塊(BLOCK)的分配和回收。在nginx中SLOT[0]~SLOT[7]分別負責區間在[1~8]、[9~16]、[17~32]、[33~64]、[65~128]、[129~256]、[257~512]、[513~1024]字節大小內存的分配,但為方便內存塊(BLOCK)的分配和回收,每個內存塊(BLOCK)的大小為各區間的上限(8、16、32、64、128、256、512、1024)。比如說:假如應用進程請求申請5個字節的空間,因5處在[1~8]的區間內,因此由SLOT[0]負責該內存的分配,但區間[1~8]的上限為8,因此即使申請5個字節,卻依然分配8字節給應用進程。以此類推:假如申請12字節,12處于區間[9~16]之間,取上限16,因此由SLOT[1]分配16個字節給應用進程;假如申請50字節,50處于區間[33~64]之間,取上限64,因此由SLOT[2]分配64個字節給應用進程;假如申請84字節,84處于區間[65~128]之間,取上限128,因此由SLOT[3]分配128個字節;...;假如申請722字節,722處于區間[513~1024]之間,取上限1024,因此由SLOT[7]分配1024字節。
  • PAGES數組:PAGES數組各成員分別負責可分配空間中各頁的查詢、分配和回收,其處理流程可參考3.2節的說明。
  • 可分配空間:SLAB在邏輯上將可分配空間劃分成M個內存頁,每頁大小為4K。每頁內存與PAGES數組成員一一對應,由PAGES數組各成員負責各內存頁的分配和回收。
  • 被浪費空間:按照每頁4K的大小對空間進行劃分時,滿足4K的空間,將作為可分配空間被PAGES數組進行管理,而最后剩余的不足4K的內存將會被舍棄,也就是被浪費了!

3.1 初始化流程

? 初始化階段主要完成對SLOT頭、SLOT數組、PAGES數組、可分配空間和被浪費空間的區域分化,各區域的劃分可參考圖1和各模塊功能的說明。nginx中slab結構體如下所示:

[cpp]?view plaincopy print?
  • typedef?struct?{??
  • ????size_t????????????min_size;?????/*?最小分配單元?*/??
  • ????size_t????????????min_shift;????/*?最小分配單元對應的位移?*/??
  • ??
  • ????ngx_slab_page_t??*pages;????????/*?頁數組?*/??
  • ????ngx_slab_page_t???free;?????????/*?空閑頁鏈表?*/??
  • ??
  • ????u_char???????????*start;????????/*?可分配空間的起始地址?*/??
  • ????u_char???????????*end;??????????/*?內存塊的結束地址?*/??
  • ??
  • ????...?????????????????????????????/*?其他變量成員(省略)?*/??
  • }ngx_slab_pool_t??
  • 代碼1 SLAB頭部結構體

    3.2 頁的管理

    3.2.1 頁的分配

    1)分配之前

    ? 在SLAB初始化之后,所有頁可以看成是一個連續的整體,其內存結構如下圖所示:

    圖2 頁的結構(分配之前)

    2)申請一頁

    ? 當申請一頁時,則將pages[0]從free鏈表中分離出去,如下圖所示:

    圖3 頁的結構(申請一頁)

    3)申請二頁

    ? 當再申請二頁時,則將page[3]和pages[4]作為一個整體從free鏈表中分離出去,如下圖所示:

    圖4 頁的結構(申請二頁)

    3.2.2 頁的回收

    1)回收一頁

    ? 當頁被回收時,被回收的頁并不會和未被分配的頁進行合并,而是通過鏈表串聯起來,這樣將造成運行的時間越長,要申請到超過一頁大小的空間也會變得越來越難。正是因為這個原因,所以slab機制不適合用來反復分配和回收超過一頁大小的內存空間。如下圖所示:[切記:slab機制不適合用來反復分配和回收超過一頁大小的內存空間]

    圖5 頁的結構(回收一頁)

    2)回收二頁

    ? 當頁被回收時,被回收的頁并不會和未被分配的頁進行合并,而是通過鏈表串聯起來,如下圖所示:

    圖6 頁的結構(回收二頁)

    3.4 SLOT的管理

    ? SLOT數組的作用可以參考第三章開頭的闡述。SLOT數組各成員相當于鏈表頭,在SLOT的分配和回收過程中,通過鏈表來組織用于分配各SIZE(1~1024)的PAGE。如,在某時刻,可能存在如下狀態:

    圖7? SLOT和PAGES的關系

    3.4.1 頁的管理

    1)初始狀態

    ? 在SLAB初始化后,slot鏈表頭的下一個節點都為NULL,如下圖所示:

    圖8 SLOT初始狀態

    2)添加一頁

    ? SLOT[2]負責32(17~32)字節空間的分配和回收,假設現申請分配24字節(17~32之間)的空間,因此將從slot[2]中分配。但在初始狀態下slot[2]的下一頁為NULL,因此需要向頁管理模塊申請一頁pages[x]內存,再將該頁加入到slot[2]的鏈表中,添加之后的內存結構如下圖所示:

    圖9 slot[2]增加一頁

    3)暫離鏈表

    ? SLOT[2]中的每一頁有128(4K/32=128)個單元,當一頁分配了128次時,表示該頁可分配單元分配完畢,此時該頁將會暫時從鏈表中剔除出去,以防止下次申請時,做無效的遍歷。如下圖所示:

    圖10 slot[2]第一頁被使用完

    ?

    4)再添一頁

    ? 當再次申請17~32字節時,此時slot[2]的后續鏈表為空,因此需要再次向頁管理申請一頁pages[y]內存,再將該頁加入到slot[2]的鏈表中,如下圖所示。如果該頁又被分配完,則進行3)的處理。

    圖11 slot[2]再添一頁

    5)重入鏈表

    ? 當所有單元被用完的頁pages[x]中的一個單元被回收時,頁pages[x]中將有1個單元可以再次被分配使用,此時應該將pages[x]重新加入到slot[2]的鏈表中,以便下次分配時可以從頁pages[x]中進行查找。此時內存組織形式如下圖所示:

    圖12 頁pages[x]重入鏈表

    6)回收整頁

    ? 當頁pages[x]所有單元被釋放后,則該頁將會被全部回收:該頁將從slot[2]的鏈表中被剔除,并將頁pages[x]重新加入到free鏈表。此時的內存結構圖如下圖所示:

    圖13 回收頁pages[x]

    ?

    3.4.2 SLOT的分配

    1)頁內結構

    ? 被加入到SLOT數組鏈表的頁在邏輯上劃分為很多的內存單元,每一小內存單元的使用情況是通過位圖進行標記的,1表示被占用,0表示未被占用。如:第20位bit的值為1時,表示第20個內存單元被占用。假如此SLOT鏈表的PAGE正好可以劃分為32塊,則其邏輯組織結構如下圖所示:

    圖14 PAGE內結構

    2)分配單元

    ? 假如此時在SLOT[s]鏈表的頁中連續申請4個內存單元,則其前4個內存單元將首先被占用,則此時的位圖結構如下圖所示:

    圖15 分配單元

    3) 釋放單元

    ? 假如此時釋放SLOT[s]鏈表頁中第3個內存單元,則此時的位圖結構如下圖所示:

    圖16 釋放單元

    ?

    轉自:"祁峰"的CSDN博客

    轉載于:https://www.cnblogs.com/zl1991/p/8335908.html

    總結

    以上是生活随笔為你收集整理的NGINX原理 之 SLAB分配机制(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。