PHP7核心剖析9之記憶體管理

不言
發布: 2023-03-23 18:12:02
原創
1726 人瀏覽過

本篇文章的內容介紹的是關於PHP7核心剖析9之記憶體管理,現在分享給大家,有需要的朋友可以參考一下

1.Zend記憶體池

記憶體池是核心中最底層的記憶體操作,定義了三種粒度的記憶體區塊:chunk、page、slot,每個chunk的大小為2M,page大小為4KB,一個chunk被切割為512個page,而一個或若干個page被切割為多個slot,所以申請記憶體時依照不同的申請大小決定具體的分配策略:
Huge(chunk): 申请内存大于2M,直接调用系统分配,分配若干个chunk
Large(page): 申请内存大于3K(3/4 page_size),小于2044K(511 page_size),分配若干个page
Small(slot): 申请内存小于等于3K(3/4 page_size)
登入後複製


## 2.zend堆疊結構

PHP7核心剖析9之記憶體管理

#chunk由512個page組成,其中第一個page用來保存chunk結構,剩下的511個page用於記憶體分配,page主要用於Large、Small兩種記憶體的分配;heap是表示記憶體池的一個結構,它是最主要的一個結構,用於管理上面三種記憶體的分配,Zend中只有一個heap結構。


3.記憶體分配

Huge分配

超過2M記憶體的申請,與通用的記憶體申請沒有太大差別,只是將申請的記憶體區塊透過單鍊錶進行了管理。 huge的分配實際上是分配多個chunk,chunk的分配也是large、small記憶體分配的基礎,它是ZendMM向系統申請記憶體的唯一粒度。在申請chunk記憶體時有一個關鍵操作,就是將記憶體位址對齊到ZEND_MM_CHUNK_SIZE,也就是說申請的chunk位址都是ZEND_MM_CHUNK_SIZE的整數倍
#Large分配

#大於3/4的page_size(4KB)且小於等於511個page_size的記憶體申請,也就是一個chunk的大小夠用(之所以是511個page而不是512個是因為第一個page始終被chunk結構佔用),如果申請多個page的話分配的時候這些page都是連續的。如果直到最後一個chunk也沒找到則重新分配一個新的chunk並插入chunk鍊錶,
chunk->free_map利用bitmap來記錄每組的page的使用情況

PHP7核心剖析9之記憶體管理#

a.首先会直接跳过group1,直接到group2检索
b.在group2中找到第一个可用page位置:67,然后向下找第一个不可用page位置:69,找到的可用内存块长度为2,小于3,表示此内存块不可用
c.接着再次在group2中查找到第一个可用page位置:71,然后向下找到第一个不可用page位置:75,内存块长度为4,大于3,表示找到一个符合的位置,虽然已经找到可用内存块但并不"完美",先将这个并不完美的page_num及len保存到best、best_len,如果后面没有比它更完美的就用它了
d.再次检索,发现group2已无可用page,进入group3,找到可用内存位置:page 130-132,大小比c中找到的合适,所以最终返回的page就是130-132
e.page分配完成后会将free_map对应整数的bit位从page_num至(page_num+page_count)置为1
登入後複製
Small分配

small記憶體指的是小於(3/4 page_size)的內存,這些記憶體首先也是申請了1個或多個page,然後再將這些page以固定大小切割了,所以第一步與上一節Large分配完全相同。 small記憶體總共有30種固定大小的規格:8,16,24,32,40,48,56,64,80,96,112,128 ... 1792,2048,2560,3072 Byte,我們把這稱為slot,這些slot的大小是有規律的:最小的slot大小為8byte,前8個slot依序遞增8byte,後面每隔4個遞增值乘以2

PHP7核心剖析9之記憶體管理

step1: 首先根据申请内存的大小在heap->free_slot中找到对应的slot规格bin_num,如果当前slot为空则首先分配对应的page,free_slot[bin_num]始终指向第一个可用的slot
step2: 如果申请内存大小对应的的slot链表不为空则直接返回free_slot[bin_num],然后将free_slot[bin_num]指向下一个空闲位置
step3: 释放内存时先将此内存的next_free_slot指向free_slot[bin_num],然后将free_slot[bin_num]指向释放的内存,也就是将释放的内存插到链表头部
登入後複製
相關建議:

PHP7核心剖析8之類 

PHP7核心剖析7之Zend引擎執行過程 

PHP7內核剖析6之函數                        



以上是PHP7核心剖析9之記憶體管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!