快速业务通道

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

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-23
: large_free_buckets[6], 就保存着大小为0b10000000到0b11111111大小的内存的指针.

  这样, 再分配内存的时候, Zend MM就可以快速定位到最可能适合的区域来查找. 提高性能.

  而, 每一个元素又同时是一个双向列表, 保持着同样size的内存块, 而左右孩子(child[0]和child[1])分别代表着键值0和1, 这个键值是指什么呢?

  我们来举个例子, 比如我向PHP申请一个true_size为0b11010大小的内存, 经过一番步骤以后, 没有找到合适的内存, PHP进入了zend_mm_search_large_block的逻辑来在large_free_buckets中寻找合适的内存:

  1. 首先, 计算true_size对应的index, 计算方法如之前描述的ZEND_MM_LARGE_BUCKET_INDEX

  2. 然后在一个位图结构中, 判断是否存在一个大于true_size的可用内存已经存在于large_free_buckets, 如果不存在就返回:

 

  size_t bitmap = heap->large_free_bitmap >> index;

  if (bitmap == 0) {

  return NULL;

  }

 

  3. 判断, free_buckets[index]是否存在可用的内存:

 

  if (UNEXPECTED((bitmap & 1) != 0))

 

  4. 如果存在, 则从free_buckets[index]开始, 寻找最合适的内存, 步骤如下:

  4.1. 从free_buckets[index]开始, 如果free_buckets[index]当前的内存大小和true_size相等, 则寻找结束, 成功返回.

  4.2. 查看true_size对应index后(true_size << (ZEND_MM_NUM_BUCKETS - index))的当前最高位, 如果为1. 则在free_buckets[index]->child[1]下面继续寻找, 如果free_buckets[index]->child[1]不存在, 则跳出. 如果true_size的当前最高位为0, 则在free_buckets[index]->child[0]下面继续寻找, 如果free_buckets[index]->child[0]不存在, 则在free_buckets[index]->child[1]下面寻找最小内存(因为此时可以保证, 在free_buckets[index]->child[1]下面的内存都是大于true_size的)

  4.3. 出发点变更为2中所述的child, 左移一位ture_size.

  5. 如果上述逻辑并没有找到合适的内存, 则寻找最小的”大块内存”:

 

  /* Search for smallest "large" free block */

  best_fit = p = heap->large_free_buckets[index + zend_mm_low_bit(bitmap)];

  while ((p = p->child[p->child[0] != NULL])) {

  if (ZEND_MM_FREE_BLOCK_SIZE(p) < ZEND_MM_FREE_BLOCK_SIZE(best_fit)) {

  best_fit = p;

  }

  }

 

  注意上面的逻辑, (p = p->child[p->child[0] != NULL]), PHP在尽量寻找最小的内存.

  为什么说, large_free_buckets是个键树呢, 从上面的逻辑我们可以看出, PHP把一个size, 按照二进制的01做键, 把内存大小信息反应到了键树上, 方便了快速查找.

  另外, 还有一个rest_buckets, 这个结构是个双向列表, 用来保存一些PHP分配后剩下的内存, 避免无意义的把剩余内存插入free_buckets带来的性能问题(此处, TIPI项目错误的描述为: “这是一个只有两个元素的数组。 而我们常用的插入和查找操作是针对第一个元素,即heap->rest_buckets[0]“).

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号