当前位置: 网学 > 编程文档 > PHP > 正文

PHP原理之内存管理中难懂的几个点

来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 13/01/02
PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等.另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们平时开发扩展, 修复PHP的bug的时候, 却对这一部分的知识需要有一个良好的理解. PHP开发组内的很多朋友也对这块不是很清楚, 所以我觉得有必要专门写一下.一些基本的概念, 我就不赘述了, 因为看代码很容易能看懂, 我这里就主要介绍几个看代码没那么容易看懂的点, 为什么这么说呢, 呵呵, 我在写文章之前, 查找了下已有的资料, 已避免重复功, 其中看到了TIPI项目对这部分的描述, 发现其中错误很多. 所以, 我想这部分就是看代码也没那么容易看懂的点目前, 英文版的介绍也在撰写中: Zend MMZend Memory Manager, 以下简称Zend MM, 是PHP中内存管理的逻辑. 其中有一个关键数据结构: zend_mm_heap:498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' style="width: 427px; height: 308px" alt="" src="/uploadfile/201301/2/66195757875.png" width="597" height="451" />Zend MM把内存非为小块内存和大块内存俩种, 区别对待, 对于小块内存, 这部分是最最常用的, 所以追求高性能. 而对于大块内存, 则追求的是稳妥, 尽量避免内存浪费.所以, 对于小块内存, PHP还引入了cache机制:498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' style="width: 416px; height: 264px" alt="" src="/uploadfile/201301/2/37195757603.png" width="521" height="385" />Zend MM 希望通过cache尽量做到, 一次定位就能查找分配.而一个不容易看懂的点是free_buckets的申明:Q: 为什么free_buckets数组的长度是ZEND_MM_NUMBER_BUCKET个?A: 这是因为, PHP在这处使用了一个技巧, 用一个定长的数组来存储ZEND_MM_NUMBER_BUCKET个zend_mm_free_block, 如上图中红色框所示. 对于一个没有被使用的free_buckets的元素, 唯一有用的数据结构就是next_free_block和prev_free_block, 所以, 为了节省内存, PHP并没有分配ZEND_MM_NUMBER_BUCKET * sizeof(zend_mm_free_block)大小的内存, 而只是用了ZEND_MM_NUMBER_BUCKET * (sizeof(*next_free_block) + sizeof(*prev_free_block))大小的内存..我们来看ZEND_MM_SMALL_FREE_BUCKET宏的定义:#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \      (zend_mm_free_block*) ((char*)&heap->free_buckets[index * 2] + \          sizeof(zend_mm_free_block*) * 2 - \          sizeof(zend_mm_small_free_block)) 之后, Zend MM 保证只会使用prev和next俩个指针, 所以不会造成内存读错..那么, 第二个不容易看懂的点, 就是PHP对large_free_buckets的管理, 先介绍分配(TIPI项目组对此部分的描述有些含糊不清):static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size) large_free_buckets可以说是一个建树和双向列表的结合:498)this.width=498;'' onmousewheel = ''javascript:return big(this)'' style="width: 413px; height: 263px" alt="" src="/uploadfile/201301/2/21195757685.png" width="555" height="351" />large_free_buckets使用一个
  • 上一篇资讯: PHP源码已迁移至GitHub
  • 网学推荐

    免费论文

    原创论文

    浏览:
    设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
    版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
    湘ICP备09003080号