内存的销毁 [ 新手入门 ]
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的方式,回收到内存池中。程序使用的所有内存,将在进程结束时统一交还给系统。
共 0 条回复
PHP学院的中学生
最后登录:2024-09-23
在线时长:168小时13分
- 粉丝29
- 金钱4725
- 威望30
- 积分6705