多数大学生出来选择的工作和专业无关
首页 > 专业知识

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

时间:2018-02-01 18:23:18 [来源]:郑州PHP培训学校

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

  PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等.
  另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们平时开发扩展, 修复PHP的bug的时候, 却对这一部分的知识需要有一个良好的理解. PHP开发组内的很多朋友也对这块不是很清楚, 所以我觉得有必要专门写一下.
  一些基本的概念, 我就不赘述了, 因为看代码很容易能看懂, 我这里就主要介绍几个看代码没那么容易看懂的点, 为什么这么说呢, 呵呵, 我在写文章之前, 查找了下已有的资料, 已避免重复功, 其中看到了TIPI项目对这部分的描述, 发现其中错误很多. 所以, 我想这部分就是看代码也没那么容易看懂的点目前, 英文版的介绍也在撰写中: Zend MM
  Zend Memory Manager, 以下简称Zend MM, 是PHP中内存管理的逻辑. 其中有一个关键数据结构: zend_mm_heap:
  Zend MM把内存非为小块内存和大块内存俩种, 区别对待, 对于小块内存, 这部分是最最常用的, 所以追求高性能. 而对于大块内存, 则追求的是稳妥, 尽量避免内存浪费.
  所以, 对于小块内存, PHP还引入了cache机制:
  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应用提速

下一篇:PHP开发应用广泛发展前景良好