### C語言的內存分配和釋放
- c是通過malloc函數申請一塊連續的指定大小的內存塊區域。其作用是在內存的動態存儲區中分配一個長度為size的連續空間。成功則返回一個指向內存首地址的指針,內存分配失敗則返回空指針NULL
- 內存使用完后調用free函數將內存塊釋放。在內存釋放的時候,不需要傳入內存的大小,因為malloc實現的時候,會比傳入的size多分配32位即4字節,第3位至31位用來存儲塊的大小,因此釋放內存的時候,通過首地址,往前移動4字節,就可以取到該快的大小值。
- **如何處理釋放后的空閑的內存塊呢**?
內存分配和釋放會導致內存被分割成若干個大小不一樣的內存塊,其中有些處于已分配狀態,有些處于空閑狀態,這兩個狀態就是通過多分配的4字節中的一個比特位來記錄的,標志位1表示已分配,0表示空閑。空閑塊可能會被組織成一個鏈表,遍歷空閑塊鏈表就可能查找到合適的內存。

- **內存池**
由于頻繁malloc分配內存塊會導致效率低下(如根據算法找出合適的內存塊、調用free等釋放內存并且可能會合并空閑塊)而且會產生很多內存碎片,也很容易造成內存泄漏。還有可能因申請不到合適的內存導致系統運行不穩定。
因此,內存池就是用來解決上述問題的,由系統提前分配好各種大小的內存,當程序需要申請內存的時候,先去內存池中查找,這樣就不用頻繁申請和釋放內存了
## php內存分配和釋放
### 內存管理器
- 使用Zend Memory Manager(Zend內存管理器)來管理內存,PHP腳本運行所需要的內存空間不是直接從系統中申請,而是調用Zend內存管理器提供的一系列接口函數(如zend\_mm\_alloc\_small)申請:如果Zend內存管理器中的可用內存夠用,直接分配給PHP查詢;否則,Zend內存管理器再從系統中申請。這樣能有效減少系統調用的次數,并優化內存空間的使用效率。
### 內存分配思想
- 通過mmap函數向系統申請大塊內存(n * chunk大小的內存),再按固定的幾種規則分割成較小的內存塊,由內存池統一管理。當調用方申請內存時,從池子中匹配已經預分配的合適大小的內存塊返回。
### 內存分類的規則
PHP7維護了3種大小的內存規格(chunk, page, slot)
- 每個chunk大小為2MB
- 每個page大小為4KB
- 一個chunk可以分割成512個page,一個page又可以分割成n個不同大小規模的slot
- 對于Zend內存管理器而言,只有chunk是通過malloc從系統中申請的內存
PHP7將Zend內存管理器申請內存按大小分成了3類:
1. **small內存**:size<=3KB,一共有30種規格大小,每當有分配請求時,在對應的空閑鏈表取合適的,若不存在合適的,則從chunk上的page分割出合適的。(具體分割看下面的“small內存分配”)
2. **large內存**:3KB<size<=(2MB-4KB),在chunk上查找滿足條件的若干個連續page,最終返回的大小為4K的整數倍。
3. **huge內存**:size>2M-4K,直接調用mmap分配2M的整數倍大小的內存。
- linux 基礎
- ln 鏈接
- linux 環境變量
- linux 進程查看
- nginx
- redis
- redis 安裝
- php 底層原理
- php源碼編譯安裝
- phpize文件
- php命令行
- php7 新特性
- php7 變量
- php7 生命周期
- php sapi運行模式
- php 內存管理
- php 運行機制和Zend虛擬機
- php垃圾回收
- php 基礎
- php.ini
- php函數
- 面向對象
- php 文件上傳
- ob緩沖和頁面靜態化
- php中的session
- php cURL擴展
- composer 應用
- php 錯誤和異常
- thinkphp
- tp6容器和依賴注入
- tp6 的服務
- tp6事件
- tp6 多應用
- tp6路由
- tp6 cache
- tp6 request
- tp6 中間件
- tp6 response
- tp6 Db
- 備忘錄
- 數據庫表