企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### C语言的内存分配和释放 - c是通过malloc函数申请一块连续的指定大小的内存块区域。其作用是在内存的动态存储区中分配一个长度为size的连续空间。成功则返回一个指向内存首地址的指针,内存分配失败则返回空指针NULL - 内存使用完后调用free函数将内存块释放。在内存释放的时候,不需要传入内存的大小,因为malloc实现的时候,会比传入的size多分配32位即4字节,第3位至31位用来存储块的大小,因此释放内存的时候,通过首地址,往前移动4字节,就可以取到该快的大小值。 - **如何处理释放后的空闲的内存块呢**? 内存分配和释放会导致内存被分割成若干个大小不一样的内存块,其中有些处于已分配状态,有些处于空闲状态,这两个状态就是通过多分配的4字节中的一个比特位来记录的,标志位1表示已分配,0表示空闲。空闲块可能会被组织成一个链表,遍历空闲块链表就可能查找到合适的内存。 ![](https://img.kancloud.cn/8b/88/8b88a91fdad5b614ce2988a690689236_699x305.png) - **内存池** 由于频繁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的整数倍大小的内存。