zend_mm_alloc_int
2015-09-11 17:31:28 3 举报
`zend_mm_alloc_int`是Zend引擎中的一个内存管理函数,主要用于在Zend虚拟机的内存堆中分配一块连续的、足够大的内存空间来存储整数值。这个函数通常在需要为整数变量或数组元素分配内存时被调用。 该函数接收一个参数,即所需的内存大小(以字节为单位),并返回一个指向新分配的内存块的指针。如果内存分配成功,返回的指针可以安全地用于存储整数值;如果内存分配失败,则返回NULL。 `zend_mm_alloc_int`函数内部实现了一套高效的内存分配策略,以确保在高并发环境下仍能保持稳定的性能。此外,它还与Zend虚拟机的其他内存管理函数协同工作,共同维护整个内存堆的健康状态。
作者其他创作
大纲/内容
break;意味着在heap-large_free_buckets[index];中没有能够“恰好”满足true_size的block
FALSE
直接进行简单处理后返回data
index++;index加一,去更大的那个bucket中去找
lookup in cache
bitmap = heap-large_free_bitmap index;将large_free_bitmap的最右边index位挪掉,剩余的最低位的位数即为第index位
TRUE
heap-cache_stat[index].miss++;
if (ZEND_MM_FREE_BLOCK_SIZE(p) ZEND_MM_FREE_BLOCK_SIZE(best_fit))如果找到更小的比truesize大的内存设为best_fit
p = heap-large_free_buckets[index];取该链表头部指针
heap-real_size += segment_size;if (heap-real_size heap-real_peak) {heap-real_peak = heap-real_size;}
不为0需要在右孩子中继续寻找if (p-child[1])判断右孩子是否有东西
size_t true_size = ZEND_MM_TRUE_SIZE(size)ture size = (size + sizeof block(16) + magicsize(4)) aligned to the nearest bigger 8-multipliestrue size = 53+16+4 = 73 aligned to 80
当前节点不能恰好满足true_size,则需要继续在孩子中寻找p = p-child[p-child[0] != NULL]如果左孩子不为空,则去右孩子如果左孩子为空,则去左孩子
rst = NULL;右孩子为空
if ZEND_MM_SMALL_SIZE(true_size)if truesize NUM_BUCKETS(sizeof(size_t) 3) + min_head(sizeof block + 8)NUM_BUCKETS即能本地系统最高支持的内存大小的bit数比如size_t为4bytes,则NUM_BUCKETS为32,在heap的各个数组中一个bit一个bucket
if ((m & (ZEND_MM_LONG_CONST(1) (ZEND_MM_NUM_BUCKETS-1))) == 0)判断当前最高位是否有0
if (segment_size real_size + segment_size heap-limit) {如果上述计算得出的segment size是否过大或者会使heap超限?
在rest_buckets里面找
heap-cache[index] != NULL
if (best_fit)这一路上是否找到不是恰好满足但是也能满足的block
if (!bitmap)如果没有更大的block链表了
bitmap = bitmap 1;当前heap-large_free_buckets[index];确定找不到可以满足truesize的block了,那么看看bitmap中更高一位是否存有东西,往存着更大size的block链表里面去找吧
index = ZEND_MM_BUCKET_INDEX(true_size)index = truesize 3 - min_head 3index = 80 3 - 24 3 = 10 - 3 = 7
heap-cache_stat[ZEND_MM_NUM_BUCKETS].miss++;记录free_buckets中miss一次
keep_rest = 1;如果申请的segement大小大于block则如有剩余,一律放入rest_buckets
/* Search for smallest \"large\" free block */ best_fit = p = heap-large_free_buckets[index + zend_mm_low_bit(bitmap)];在更大的bucket里面寻找,先将这个更大的bucket的头部作为目前的最优选择best_fit
zend_mm_safe_errorOut of memory
为0则需要在左孩子中继续寻找if (p-child[1])为避免左孩子中找不到合适的block,我们也记住当前的右孩子,一旦左孩子中找不到,我们可以使用右孩子中最小的block来满足truesize
return NULL;
)
while ((p = p-child[p-child[0] != NULL]))继续在孩子中寻找更小的block直到当前节点没有左孩子为止
heap-cache_stat[ZEND_MM_NUM_BUCKETS].hit++;记录free_buckets中命中一次
somthing i dont understand
return best_fit-next_free_block;
if (!best_fit)如果上面所有步骤都找不到(包括rest)
for (m = true_size (ZEND_MM_NUM_BUCKETS - index); ; m = 1) 先将truesize左移直到将最高位挤出,然后每次loop都将目前最高位挤出
segment_size = heap-block_size;如果可以满足,就申请block_size大小的内存,即block_size是heap向系统申请内存的最小单元
if (!best_fit && heap-real_size = heap-limit - heap-block_size)如果上面步骤都没有找到而整个heap哪怕再添加一个block就大小超限了
找到了就设置best_fit
if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size))如果p指向的block的size恰好满足true_size
rst = p-child[1];记录当前右孩子
out of memory
zend_mm_safe_errorAllowed memory size of %ld bytes exhausted
return p-next_free_block;
if true_size size
somethingi dont understand
segment-size = segment_size; segment-next_segment = heap-segments_list;heap-segments_list = segment;
return p-next_free_block;
p = p-child[0];
index += zend_mm_low_bit(bitmap)获取挪位后剩余的bitmap中最低位是第几位,加在index上比如1010的最低位是1,从右数第2个,index为7+1=8代表在free_buckets中能满足true_size的最小bucket为第8个
if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size))当前节点block的大小是否正好满足truesize通过p-info._size来判断
if (p-child[0])左孩子是否有东西
if (UNEXPECTED((bitmap & 1) != 0))large_free_buckets[index]这一链表是否有block
segment = (zend_mm_segment *) ZEND_MM_STORAGE_ALLOC(segment_size);使用底层storage层的malloc类似函数去真正地向系统申请内存
只好向系统申请新的内存添入heap了新内存是以segment为单位申请的,放入segment_list当中,然后将segment按需求一次次地切分为一个个block,然后用free_buckets等链表将这些block连起来
e
for (p = rst; p; p = p-child[p-child[0] != NULL]) 如果在上面的搜寻中,虽然没有找到“恰好”满足true_size的block但记录了最后一个左孩子存在的分支的右孩子rst如果记录了rst,则在rst里面继续寻找
if (true_size heap-block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE))如果扣除每个segment必要的segment结构体与最后一个守卫block的大小,heap设定的block_size无法满足truesize的话
if (bitmap == 0)判断large_free_buckets[index or larger]中是否有blocks,来满足truesize的需求
best_fit = p;
if (bitmap)校验原第8位或更高位数是否有1也就是free_buckets[index or larger]是否有可用block,来满足true_size的需求
index = ZEND_MM_LARGE_BUCKET_INDEX(true_size);index=truesize的最高位数的1的位数,比如index = LARGE_INDEX(80 = 1010000) = 6
已设置好best_fit,跳至zend_mm_finished_searching_for_block
p = p-child[1];
if (!segment)是否申请失败?
best_fit = heap-free_buckets[index*2];直接取出free_buckets中第index个双向链表头部的block
bitmap = heap-free_bitmap index;将free_bitmap挪掉7位,目前最低位也就是原来从右数第八个位
return null;large_free_buckets里面也没有
0 条评论
下一页