周梦康 发表于 2016-02-28 6981 次浏览 标签 : PHP 扩展开发

PHP 扩展开发的文章,我均已更新至《TIPI》(下面的博文可能已经过时,以 TIPI 上的内容为准)。

本篇可以说是TIPIT内存管理的笔记,仅仅供自己梳理知识使用,如果需要系统了解请直接阅读《TIPIT

PHP属于高级语言,语言级别并没有内存的概念,在使用过程中完全不需要主动申请或释放内存。但是在扩展开发中我们需要使用C或C++来编写代码,就避免不了申请和释放内存了。

先大致了解下PHP内存管理分层图:

PHP5 扩展开发之内存管理 API

PHP的内存管理可以被看作是分层(hierarchical)的。 它分为三层:存储层(storage)、堆层(heap)和接口层(emalloc/efree)。 供扩展调用的则是接口层,这些宏的定义在Zend/zend_alloc.h,它们与原生C函数的对应关系如下:

C语言原生函数PHP内核封装后的函数
void *malloc(size_t count);void *emalloc(size_t count);
void *pemalloc(size_t count, char persistent);
void *calloc(size_t count);void *ecalloc(size_t count);
void *pecalloc(size_t count, char persistent);
void *realloc(void *ptr, size_t count);void *erealloc(void *ptr, size_t count);
void *perealloc(void *ptr, size_t count, char persistent);
void *strdup(void *ptr);void *estrdup(void *ptr);
void *pestrdup(void *ptr, char persistent);
void *estrndup(const char *s, unsigned int length);
void *pestrndup(void *ptr, unsigned int length, char persistent);
void free(void *ptr);void efree(void *ptr);
void pefree(void *ptr, char persistent);

这些宏相当于一个接口层或中间层,定义了一个高层次的接口,使得调用更加容易。它隔离了外部调用和PHP内部的内存管理,实现了一种松耦合关系。虽然PHP不限制这些原生的C函数的使用, 但是官方文档还是建议使用这些宏。

使用这些宏的优点是:任何分配的内存在偶然情况下如果没有被释放,则会在请求的最后被释放。因此,真正的内存泄漏不会产生。然而,不要依赖这一机制,从调试和性能两个原因来考虑,应当确保释放应该释放的内存。剩下的优点是在多线程环境下性能的提高,调试模式下检测内存错误等。还有一个重要的原因,你不需要检查这些内存分配函数的返回值是否为null。当内存分配失败,它们会发出E_ERROR错误,从而决不会返回到扩展。

参考

http://www.laruence.com/2009/04/28/719.html

http://www.php-internals.com/book/?p=chapt06/06-02-php-memory-manager


评论列表