摘要:但在多線程模式下會(huì)有多個(gè),也就是說(shuō)每個(gè)線程都有一個(gè)獨(dú)立的內(nèi)存池內(nèi)存分配分配超過(guò)內(nèi)存的申請(qǐng),與通用的內(nèi)存申請(qǐng)沒(méi)有太大差別,只是將申請(qǐng)的內(nèi)存塊通過(guò)單鏈表進(jìn)行了管理。的分配實(shí)際就是分配多個(gè),的分配也是內(nèi)存分配的基礎(chǔ),它是向系統(tǒng)申請(qǐng)內(nèi)存的唯一粒度。
1.Zend內(nèi)存池
內(nèi)存池是內(nèi)核中最底層的內(nèi)存操作,定義了三種粒度的內(nèi)存塊:chunk、page、slot,每個(gè)chunk的大小為2M,page大小為4KB,一個(gè)chunk被切割為512個(gè)page,而一個(gè)或若干個(gè)page被切割為多個(gè)slot,所以申請(qǐng)內(nèi)存時(shí)按照不同的申請(qǐng)大小決定具體的分配策略:
Huge(chunk): 申請(qǐng)內(nèi)存大于2M,直接調(diào)用系統(tǒng)分配,分配若干個(gè)chunk Large(page): 申請(qǐng)內(nèi)存大于3K(3/4 page_size),小于2044K(511 page_size),分配若干個(gè)page Small(slot): 申請(qǐng)內(nèi)存小于等于3K(3/4 page_size)
2.zend堆結(jié)構(gòu)
chunk由512個(gè)page組成,其中第一個(gè)page用于保存chunk結(jié)構(gòu),剩下的511個(gè)page用于內(nèi)存分配,page主要用于Large、Small兩種內(nèi)存的分配;heap是表示內(nèi)存池的一個(gè)結(jié)構(gòu),它是最主要的一個(gè)結(jié)構(gòu),用于管理上面三種內(nèi)存的分配,Zend中只有一個(gè)heap結(jié)構(gòu)。但在多線程模式下(ZTS)會(huì)有多個(gè)heap,也就是說(shuō)每個(gè)線程都有一個(gè)獨(dú)立的內(nèi)存池
3.內(nèi)存分配
Huge分配
超過(guò)2M內(nèi)存的申請(qǐng),與通用的內(nèi)存申請(qǐng)沒(méi)有太大差別,只是將申請(qǐng)的內(nèi)存塊通過(guò)單鏈表進(jìn)行了管理。huge的分配實(shí)際就是分配多個(gè)chunk,chunk的分配也是large、small內(nèi)存分配的基礎(chǔ),它是ZendMM向系統(tǒng)申請(qǐng)內(nèi)存的唯一粒度。在申請(qǐng)chunk內(nèi)存時(shí)有一個(gè)關(guān)鍵操作,那就是將內(nèi)存地址對(duì)齊到ZEND_MM_CHUNK_SIZE,也就是說(shuō)申請(qǐng)的chunk地址都是ZEND_MM_CHUNK_SIZE的整數(shù)倍
Large分配
大于3/4的page_size(4KB)且小于等于511個(gè)page_size的內(nèi)存申請(qǐng),也就是一個(gè)chunk的大小夠用(之所以是511個(gè)page而不是512個(gè)是因?yàn)榈谝粋€(gè)page始終被chunk結(jié)構(gòu)占用),如果申請(qǐng)多個(gè)page的話分配的時(shí)候這些page都是連續(xù)的 。如果直到最后一個(gè)chunk也沒(méi)找到則重新分配一個(gè)新的chunk并插入chunk鏈表,
chunk->free_map利用bitmap來(lái)記錄每組的page的使用情況
a.首先會(huì)直接跳過(guò)group1,直接到group2檢索 b.在group2中找到第一個(gè)可用page位置:67,然后向下找第一個(gè)不可用page位置:69,找到的可用內(nèi)存塊長(zhǎng)度為2,小于3,表示此內(nèi)存塊不可用 c.接著再次在group2中查找到第一個(gè)可用page位置:71,然后向下找到第一個(gè)不可用page位置:75,內(nèi)存塊長(zhǎng)度為4,大于3,表示找到一個(gè)符合的位置,雖然已經(jīng)找到可用內(nèi)存塊但并不"完美",先將這個(gè)并不完美的page_num及l(fā)en保存到best、best_len,如果后面沒(méi)有比它更完美的就用它了 d.再次檢索,發(fā)現(xiàn)group2已無(wú)可用page,進(jìn)入group3,找到可用內(nèi)存位置:page 130-132,大小比c中找到的合適,所以最終返回的page就是130-132 e.page分配完成后會(huì)將free_map對(duì)應(yīng)整數(shù)的bit位從page_num至(page_num+page_count)置為1
Small分配
small內(nèi)存指的是小于(3/4 page_size)的內(nèi)存,這些內(nèi)存首先也是申請(qǐng)了1個(gè)或多個(gè)page,然后再將這些page按固定大小切割了,所以第一步與上一節(jié)Large分配完全相同。small內(nèi)存總共有30種固定大小的規(guī)格:8,16,24,32,40,48,56,64,80,96,112,128 ... 1792,2048,2560,3072 Byte,我們把這稱之為slot,這些slot的大小是有規(guī)律的:最小的slot大小為8byte,前8個(gè)slot依次遞增8byte,后面每隔4個(gè)遞增值乘以2
step1: 首先根據(jù)申請(qǐng)內(nèi)存的大小在heap->free_slot中找到對(duì)應(yīng)的slot規(guī)格bin_num,如果當(dāng)前slot為空則首先分配對(duì) 應(yīng)的page,free_slot[bin_num]始終指向第一個(gè)可用的slot step2: 如果申請(qǐng)內(nèi)存大小對(duì)應(yīng)的的slot鏈表不為空則直接返回free_slot[bin_num],然后將free_slot[bin_num]指向 下一個(gè)空閑位置 step3: 釋放內(nèi)存時(shí)先將此內(nèi)存的next_free_slot指向free_slot[bin_num],然后將free_slot[bin_num]指向釋放的內(nèi)存,也就是將釋放的內(nèi)存插到鏈表頭部
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/28584.html
摘要:插入一個(gè)元素時(shí)先將元素按先后順序插入數(shù)組,位置是,再根據(jù)的哈希值映射到散列表中的某個(gè)位置,將存入這個(gè)位置查找時(shí)先在散列表中映射到,得到在數(shù)組的位置,再?gòu)臄?shù)組中取出元素。目前只有兩種類型會(huì)使用這種機(jī)制。 1.變量結(jié)構(gòu) typedef struct _zval_struct zval; typedef union _zend_value { zend_long ...
摘要:中專門(mén)為解決線程安全的問(wèn)題抽象出了一個(gè)線程安全資源管理器,實(shí)現(xiàn)原理比較簡(jiǎn)單既然共用資源這么困難那么就干脆不共用,各線程不再共享同一份全局變量,而是各復(fù)制一份,使用數(shù)據(jù)時(shí)各線程各取自己的副本,互不干擾。 1.線程安全資源管理器 PHP的SAPI多數(shù)是單線程環(huán)境,比如cli、fpm、cgi,每個(gè)進(jìn)程只啟動(dòng)一個(gè)主線程,這種模式下是不存在線程安全問(wèn)題的,但是也有多線程的環(huán)境,比如Apache,...
摘要:是與之間數(shù)據(jù)交換的一種協(xié)議。當(dāng)收到這個(gè)請(qǐng)求后,會(huì)啟動(dòng)對(duì)應(yīng)的程序,這里就是的解析器。接下來(lái)解析器會(huì)解析文件,初始化執(zhí)行環(huán)境,然后處理請(qǐng)求,再以規(guī)定規(guī)定的格式返回處理后的結(jié)果,退出進(jìn)程,再把結(jié)果返回給瀏覽器。 CGI:是 Web Server 與 Web Application 之間數(shù)據(jù)交換的一種協(xié)議。FastCGI:同 CGI,是一種通信協(xié)議,但比 CGI 在效率上做了一些優(yōu)化。PHP-...
摘要:是與之間數(shù)據(jù)交換的一種協(xié)議。當(dāng)收到這個(gè)請(qǐng)求后,會(huì)啟動(dòng)對(duì)應(yīng)的程序,這里就是的解析器。接下來(lái)解析器會(huì)解析文件,初始化執(zhí)行環(huán)境,然后處理請(qǐng)求,再以規(guī)定規(guī)定的格式返回處理后的結(jié)果,退出進(jìn)程,再把結(jié)果返回給瀏覽器。 CGI:是 Web Server 與 Web Application 之間數(shù)據(jù)交換的一種協(xié)議。FastCGI:同 CGI,是一種通信協(xié)議,但比 CGI 在效率上做了一些優(yōu)化。PHP-...
摘要:是與之間數(shù)據(jù)交換的一種協(xié)議。當(dāng)收到這個(gè)請(qǐng)求后,會(huì)啟動(dòng)對(duì)應(yīng)的程序,這里就是的解析器。接下來(lái)解析器會(huì)解析文件,初始化執(zhí)行環(huán)境,然后處理請(qǐng)求,再以規(guī)定規(guī)定的格式返回處理后的結(jié)果,退出進(jìn)程,再把結(jié)果返回給瀏覽器。 CGI:是 Web Server 與 Web Application 之間數(shù)據(jù)交換的一種協(xié)議。FastCGI:同 CGI,是一種通信協(xié)議,但比 CGI 在效率上做了一些優(yōu)化。PHP-...
閱讀 3736·2023-04-25 18:41
閱讀 1169·2021-11-11 16:55
閱讀 1823·2021-09-22 15:54
閱讀 3069·2021-09-22 15:51
閱讀 3545·2019-08-30 15:55
閱讀 1937·2019-08-30 14:19
閱讀 1277·2019-08-29 10:57
閱讀 1699·2019-08-29 10:56