浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层

浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层

内容导读

收集整理的这篇技术教程文章主要介绍了浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3042字,纯文字阅读大概需要5分钟

内容图文

这篇文章主要介绍了关于浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层
emalloc/efree层是整个内存体系中最上层结构,它通过与堆层的交换使用PHP自带的内存管理机制。如果有设置USE_ZEND_ALLOC为0,则直接使用malloc/free等函数直接操作内存。
这里将从emalloc与efree两个函数的实现解析emalloc/efree层与堆层的交互,及堆层对于内存的管理机制。

【emalloc】
emalloc函数是从zend_alloc.h 70行开始。
emalloc是一个宏,其对应了_emalloc函数。
在_emalloc函数中,如果未使用zend的内存管理机制,则直接调用malloc函数,否则调用

_zend_mm_alloc_int[emalloc() -> _emalloc() -> _zend_mm_alloc_int() ]

在_zend_mm_alloc_int函数中,程序会处理真实需要的内存小于或大于等于ZEND_MM_MAX_SMALL_SIZE(272)两种情况,如果小于ZEND_MM_MAX_SMALL_SIZE,则会搜索free_buckets,看是否有合适的内存块,如果可以在free_buckets中找到合适的块使用,同直接跳转到zend_mm_finished_searching_for_block,否则执行zend_mm_search_large_block()

[emalloc() -> _emalloc() -> _zend_mm_alloc_int() -> zend_mm_search_large_block()]
zend_mm_search_large_block函数用来在large_free_buckets中查找合适的内存块。其中当对于ZEND_MM_LARGE_BUCKET_INDEX(true_size)大小的没有找到时,需要查找更大块列表中的最小块。

如果在大块列表和小块列表中都没有,则需要从剩余列表块中查找,如果找到,则同样跳转到zend_mm_finished_searching_for_block
如果三个列表中都没有找到,则需要重新增加内存分配。此时调用storage层的分配函数进行分配,其中内存的大小,如果需要分配的内存大于block_size,则需要根据大小重新计算,否则直接分配block_size大小的内存。
分配内存完后,需要重新整理堆,此时需要重新计算堆中的内存大小,将新分配的内存添加到segments_list的前面。

如果在上面的操作中是直接跳转到zend_mm_finished_searching_for_block,则需要将使用了的内存块从对应的列表中移除(此处应该是一个标记的过程,伪移除)

接下来,根据剩下的内存大小,将其移到空闲列表或剩余列表。

最后返回分配的块。

在emalloc整个过程中,有以下一些注意点。
ZEND_MM_BUCKET_INDEX(true_size)定位在bucket中的位置,这个值大于等于0,小于32。
其实现如下:

#define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))

free_bitmap和large_free_bitmap的值都是0到31。

【efree】
efree函数是从zend_alloc.h 72行开始。
efree是一个宏,其对应了_efree函数。
在_efree函数中,如果未使用zend的内存管理机制,则直接调用free函数,否则调用_

zend_mm_free_int[efree() -> _efree() -> _zend_mm_free_int() ]

堆首先将整个堆的大小减少,如果当前块的后一个块是空闲块,则将后一个空闲块从空闲块列表中删除并与当前块合并,如果当前块的前一个块是空闲块,则将前一个空闲块从空闲块列表中删除并与当前块合并,指针指向前一个空闲块。如果此时当前块是开始的块,则调用zend_mm_del_segment将整段内存清除,如果不是开始块,则将合并后的块添加到空闲块列表。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

浅谈PHP源码三十一:PHP内存池中的堆(heap)层基础

浅谈PHP源码三十:PHP内存池中的存储层

浅谈PHP源码二十九:关于接口的继承

以上就是浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层的详细内容,更多请关注Gxl网其它相关文章!

内容总结

以上是为您收集整理的浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层全部内容,希望文章能够帮你解决浅谈PHP源码三十二:PHP内存池中的emalloc/efree层与堆(heap)层所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。

内容备注

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。


本文关键词:

联系我们

在线咨询:点击这里给我发消息

邮件:w420220301@qq.com