迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

ZEND_MM_SMALL_SIZE 详细讲解

作者:迹忆客 最近更新:2022/12/26 浏览次数:

ZEND_MM_SMALL_SIZE(true_size) 是判断 true_size 大小是否符合小块大小。可以理解为一个boolean

#define ZEND_MM_SMALL_SIZE(true_size)  (true_size < ZEND_MM_MAX_SMALL_SIZE) 

ZEND_MM_MAX_SMALL_SIZE 表示小块内存最大能容纳的数据的大小

#define ZEND_MM_MAX_SMALL_SIZE ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)

这个计算过程有点复杂,拆开来看

#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3)

#define ZEND_MM_ALIGNMENT_LOG2  3

#define ZEND_MM_ALIGNED_MIN_HEADER_SIZE (ZEND_MM_MIN_ALLOC_BLOCK_SIZE>ZEND_MM_ALIGNED_FREE_HEADER_SIZE?ZEND_MM_MIN_ALLOC_BLOCK_SIZE:ZEND_MM_ALIGNED_FREE_HEADER_SIZE)  // 最小需要的free_block 的头部的大小,也就是ZEND_MM_MIN_ALLOC_BLOCK_SIZE和ZEND_MM_ALIGNED_FREE_HEADER_SIZE 二者之间最大的值

崩溃了,一环套一环,宏 ZEND_MM_ALIGNED_MIN_HEADER_SIZE 定义稍微复杂,继续拆分这个宏

#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE) // 最小需要分配的块的大小

#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block)) // 结构体zend_mm_small_free_block 的大小,但就这个宏而言无特殊的逻辑含义   56

// 拆分 宏 ZEND_MM_MIN_ALLOC_BLOCK_SIZE
#define ZEND_MM_ALIGNED_HEADER_SIZE            ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))  // free_block 头部大小

#if ZEND_MM_HEAP_PROTECTION
# define END_MAGIC_SIZE sizeof(unsigned int)
#else
# define END_MAGIC_SIZE 0
#endif

衍生出了这样的两个宏定义,现在看应该就剩下 宏 ZEND_MM_ALIGNED_SIZE(size)了。看这个宏的定义

#define ZEND_MM_ALIGNED_SIZE(size) (((size) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)

这里面又涉及到两个宏ZEND_MM_ALIGNMENTZEND_MM_ALIGNMENT_MASK 看起来这两个宏是有些关联的

#define ZEND_MM_ALIGNMENT 8
#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)

好了,到这里已经到尽头了。现在我们往回带入。通过简单的二进制的计算,可以发现 宏 ZEND_MM_ALIGNED_SIZE(size) 是用来将size大小进行对齐的。即将 size 对齐为大于size的8的最小整数倍。举个例子:

  • size = 256

    256: 100000000 ZEND_MM_ALIGNED_SIZE(256) => (((256)+8-1) & ~(8-1)) 转换成二进制为 100000000 + 000000111 & 111111000 = 100000000 256 本身能被 8 整除, 所以对齐之后还是 256

  • size = 257

    257: 100000001 ZEND_MM_ALIGNED_SIZE(257) => (((257)+8-1) & ~(8-1)) 转换成二进制为 100000001 + 000000111 & 111111000 = 100001000 => 264 为 8 的倍数

  • size = 263

    263: 100000111 ZEND_MM_ALIGNED_SIZE(263) => (((263)+8-1) & ~(8-1)) 转换成二进制为 100000111 + 000000111 & 111111000 = 100001000 => 264 为 8 的倍数

好了,现在清楚了宏ZEND_MM_ALIGNED_SIZE(size)的作用。那继续往回带入可以得出中间很多宏的值和一些特殊含义,已经在上面代码里写了注释。 最终可以计算出宏 ZEND_MM_MAX_SMALL_SIZE,在我的机器上为 544 。 最终也就能理解了宏ZEND_MM_SMALL_SIZE

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

PHP 扩展运算符

发布时间:2023/03/28 浏览次数:97 分类:PHP

本篇文章介绍了 PHP 中的扩展运算符。

如何使用 CLion 开发调试 PHP 扩展

发布时间:2021/07/02 浏览次数:231 分类:PHP

php 扩展的创建这里就不再赘述,使用ext_skel 生成一个框架,然后编辑相应的文件,编译安装,最后在php.ini 配置文件中加入生成的扩展 例如 my_ext.so

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便