php内核探索笔记-内存的申请与释放
2015-12-16 19:01
931 查看
内存申请
PHP底层对内存的管理, 围绕着小块内存列表(free_buckets)、 大块内存列表(large_free_buckets)和 剩余内存列表(rest_buckets)三个列表来分层进行的。 ZendMM向系统进行的内存申请,并不是有需要时向系统即时申请, 而是由ZendMM的最底层(heap层)先向系统申请一大块的内存,通过对上面三种列表的填充, 建立一个类似于内存池的管理机制。这样做的好处是避免了PHP向系统频繁的内存申请操作;缺点是随着程序的运行时间的变长, 内存的使用情况会“越来越多”(PHP5.2及更早版本)。
在php中可以调用emalloc函数来实现ZendMM代替系统级的内存分配。
在emalloc中判断是否进行ZendMM管理,如果未采用则调用_malloc函数进行内存分配。(这里的_malloc可以是malloc,win32,mmap_anon,mmap_zero中的一种)
不使用ZendMM进行内存管理,唯一的用途是打开enable-debug开关后, 可以更方便的追踪内存的使用情况。
php申请流程
内存检查。 对要申请的内存大小进行检查,如果太大(超出memory_limit则报 Out of Memory);
如果命中缓存,使用fastcache得到内存块(详见第五节),然后直接进行第5步;
在ZendMM管理的heap层存储中搜索合适大小的内存块,在这一步骤ZendMM通过与ZEND_MM_MAX_SMALL_SIZE进行大小比较, 把内存请求分为两种类型:large和small。small类型的的请求会先使用zend_mm_low_bit函数在mm_heap中的free_buckets中查找,未找到则使用与large类型相同的方式:使用zend_mm_search_large_block函数在“大块”内存(_zend_mm_heap->large_free_buckets)中进行查找。如果还没有可以满足大小需求的内存,最后在rest_buckets中进行查找。 也就是说,内存的分配是在三种列表中小到大进行的。找到可以使用的block后,进行第5步;
如果经过第3步的查找还没有找到可以使用的资源(请求的内存过大),需要使用ZEND_MM_STORAGE_ALLOC函数向系统再申请一块内存(大小至少为ZEND_MM_SEG_SIZE),然后直接将对齐后的地址分配给本次请求。跳到第6步;
使用zend_mm_remove_from_free_list函数将已经使用block节点在zend_mm_free_block中移除;
内存分配完毕,对zend_mm_heap结构中的各种标识型变量进行维护,包括large_free_buckets,peak,size等;
返回分配的内存地址;
内存释放
ZendMM在内存销毁的处理上采用与内存申请相同的策略,当程序unset一个变量或者是其他的释放行为时, ZendMM并不会直接立刻将内存交回给系统,而是只在自身维护的内存池中将其重新标识为可用。按照内存的大小整理到上面所说的三种列表(small,large,free)之中,以备下次内存申请时使用。释放流程
内存的销毁首先要进行是否放回cache的判断。如果内存的大小满足ZEND_MM_SMALL_SIZE并且cache还没有超过系统设置的ZEND_MM_CACHE_SIZE,那么,当前内存块zend_mm_block就会被放回mm_heap->cache中。
根据当前要销毁的内存块mm_block在zend_mm_heap 双向链表中所处的位置进行不同的操作。
如果下一个节点还是free的内存,则将下一个节点合并;
如果上一相邻节点内存块为free,则合并到上一个节点;
如果只是普通节点,刚使用 zend_mm_add_to_free_list或者zend_mm_del_segment 进行回收。
相关文章推荐
- 一个关于if else容易迷惑的问题
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- Linux 自检和 SystemTap
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- Php Installing An Expansion
- IE7降低内存和降低CPU的几个技巧
- 如何高效的使用内存
- DOS下内存的配置
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- XP/win2003下发现1G的内存比512M还慢的解决方法
- PHP 5.3.0 安装分析心得