设计php内存管理机制,PHP内存管理机制

PHP不需要显式内存管理,由Zend引擎负责管理

PHP的内存管理,包括:足够内存

可用内存获取部分内存

使用后的内存,是否销毁还是重新分配

Zend内存管理机制:

接口层

一些宏定义 ### 堆层Heap(_zend_mm_heap) 初始化内存,调用zend_mm_startup PHP内存管理维护3个列表: 1. 小块内存列表free_buckets 2. 大块内存列表large_free_buckets 3. 剩余内存列表rest_buckets

2个HashTable结构,难点是查找和计算内存地址

free_buckets

Hash函数为:

#define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))

large_free_buckets

Hash函数为:

#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)

static inline unsigned int zend_mm_high_bit(size_t _size){

..// 省略若干不同环境的实现

unsignedint n =0;

while(_size !=0) {

_size = _size >>1; n++;}

return n-1;

}

存储层内存分配方式对堆层透明化,实现分离

不同的内存分配方案,有对应的处理函数

PHP底层对内存的管理,就是围绕这小块内存列表、大块内存列表和剩余内存列表来分层进行的

ZendMM向系统进行的内存申请,并不是有需要时向系统即时申请

而是由ZendMM的最底层(heap层)先向系统申请一大块的内存

通过对上面三种列表的填充, 建立一个类似于内存池的管理机制

在程序运行需要使用内存的时候,ZendMM会在内存池中分配相应的内存供使用

这样做的好处是避免了PHP向系统频繁的内存申请操作

ZendMM对内存分配的处理步骤:内存检查

命中缓存,找到内存块,转5

在Heap层中搜索合适大小的内存块,找到后,转5

3中未找到,使用ZEND_MM_STORAGE_ALLOC申请新内存块,转6

使用zend_mm_remove_from_free_list将已经使用的block节点在zend_mm_free_list中删除

内存分配完毕,对zend_mm_heap结构中的各种标志型变量进行维护,包括large_free_buckets、peak、size等

返回分配的内存地址

内存的销毁

当程序unset一个变量或者其他的释放行为时,ZendMM并不会立即将内存交回给系统。而是在自己维护的内存池中将其重新标示为可用

ZendMM将内存块以整理回收到zend_mm_heap的方式,回收到内存池中。程序使用的所有内存,在进程结束时统一交还给系统。

垃圾回收

PHP5.3之前

引用计数方式的内存动态管理

PHP中所有的变量都是以zval变量的形式存在,当变量的引用计数变为0时,PHP将在内存中销毁这个变量。

PHP5.3的垃圾回收

为了打破引用计数中的循环引用,引入垃圾回收机制

struct _zval_struct {

zvalue_value value;

zend_unit refcount__gc;

zend_uchar type;

zend_uchar is_ref__gc;

}

该垃圾回收算法描述:

首先,PHP会分配一个固定大小的根缓冲区,用于存放固定数量的zval变量。默认10,000

当根缓冲区满时,PHP就会执行垃圾回收。算法如下:对每个根缓冲区中的根zval按照深入优先遍历算法遍历到所有的zval,并将每个zval的refcount减1并且标记,防止多减

再对每个根缓冲区中的根zval深度优先遍历,如果某个zval的refcount不为0,则+1,否则保持不变

清空缓冲区中的所有根,然后销毁所有refcount为0的zval,并回收其内存

####与垃圾回收算法相关的PHP配置

1、可以通过修改php.ini中的zend.enable_gc来打开或关闭PHP的垃圾回收机制,也可以通过调用gc_enable()或gc_disable()打开或关闭PHP的垃圾回收机制。

2、在PHP5.3中即使关闭了垃圾回收机制,PHP仍然会记录可能根到根缓冲区,只是当根缓冲区满额时,PHP不会自动运行垃圾回收

3、当然,任何时候您都可以通过手工调用gc_collect_cycles()函数强制执行内存回收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值