PHP学院的中学生 2021-02-24 10:10:49 1110次浏览 0条回复 0 0 0

ZendMM在内存销毁的处理上采用与内存申请相同的策略,当程序unset一个变量或者是其他的释放行为时,ZendMM并不会直接立刻将内存交回给系统,而是只在自身维护的内存池中将其重新标识为可用,按照内存的大小整理到上面所说的三种列表(small,large,free)之中,以备下次内存申请时使用。

关于变量销毁的处理,还涉及较多的其他操作,请参看变量的创建和销毁

内存销毁的最终实现函数是_efree。在_efree中,内存的销毁首先要进行是否放回cache的判断。如果内存的大小满足ZEND_MM_SMALL_SIZE并且cache还没有超过系统设置的ZEND_MM_CACHE_SIZE,那么,当前内存块zend_mm_block就会被放回mm_heap->cache中。如果内存块没有被放回cache,则使用下面的代码进行处理:

zend_mm_block mm_block; //要销毁的内存块 zend_mm_block next_block; ... next_block = ZEND_MM_BLOCK_AT(mm_block, size); if (ZEND_MM_IS_FREE_BLOCK(next_block)) {

zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block);
size += ZEND_MM_FREE_BLOCK_SIZE(next_block);

}
if (ZEND_MM_PREV_BLOCK_IS_FREE(mm_block)) {

mm_block = ZEND_MM_PREV_BLOCK(mm_block);
zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) mm_block);
size += ZEND_MM_FREE_BLOCK_SIZE(mm_block);

}
if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&

ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(mm_block, size))) {
zend_mm_del_segment(heap, (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE));

} else {

ZEND_MM_BLOCK(mm_block, ZEND_MM_FREE_BLOCK, size);
zend_mm_add_to_free_list(heap, (zend_mm_free_block *) mm_block);

} 这段代码逻辑比较清晰,主要是根据当前要销毁的内存块mm_block在zend_mm_heap双向链表中所处的位置进行不同的操作。如果下一个节点还是free的内存,则将下一个节点合并;如果上一相邻节点内存块为free,则合并到上一个节点;如果只是普通节点,刚使用 zend_mm_add_to_free_list或者zend_mm_del_segment进行回收。

就这样,ZendMM将内存块以整理收回到zend_mm_heap的方式,回收到内存池中。程序使用的所有内存,将在进程结束时统一交还给系统。

    没有找到数据。
您需要登录后才可以回复。登录 | 立即注册