php之内存管理基础

简介: <p class="para" style="margin-top:0px; margin-bottom:1.5rem; color:rgb(51,51,51); font-family:'Fira Sans','Source Sans Pro',Helvetica,Arial,sans-serif; font-size:16px; line-height:24px; background

用 C 语言编程时,开发者要手工地进行内存管理。因为 PHP 经常用作 Web 服务器的模块,内存管理与预防内存泄漏紧密关联。此外要知道 PHP 可能用于线程环境中,这意味着全局变量可能导致竞争状况。有关线程内全局数据处理的信息请参见作为线程隔离设施的 线程安全的资源管理器

此外,Zend 引擎要面对一个十分特殊的使用模式:在一段比较短的时间内,许多 zval 结构大小的内存块和其他的小内存块被申请又再被释放。PHP 的内存管理也很重视 memory_limit(内存限制)

为了满足以上的需求,Zend 引擎提供为了处理请求相关数据提供了一种特殊的内存管理器。请求相关数据是指只需要服务于单个请求,最迟会在请求结束时释放的数据。扩展开发者主要接触下表中列出的惯例。虽然一些所提供的便捷功能是用宏实现的,但在本文中会象函数一样对待。

主要的内存 APIs 原型 说明 void *emalloc(size_t size) 分配  size 字节的内存。 void *ecalloc(size_t nmemb, size_t size) 给  nmemb 元素分配  size 字节的缓冲区并初始化为零。 void *erealloc(void *ptr, size_t size) 修改使用  emalloc 分配的缓冲区  ptr 的大小为  size 字节。 void efree(void *ptr) 释放  ptr 指向的缓冲区。缓冲区必须是由  emalloc 分配的。 void *safe_emalloc(size_t nmemb, size_t size, size_t offset) 分配缓冲区来存放每块大小为  size 字节的  nmemb 块,并附加  offset 字节。类似于  emalloc(nmemb * size + offset),但增加了针对溢出的特殊保护。 char *estrdup(const char *s) 分配一个可存放 NULL 结尾的字符串  s 的缓冲区,并将  s 复制到缓冲区内。 char *estrndup(const char *s, unsigned int length) 类似于  estrdup,但 NULL 结尾的字符串长度是已知的。

Note和与 C 标准库相似的部分不同,如果分配请求的内存出错,Zend 引擎的内存管理函数不会返回 NULL 值,而会跳出并中止当前请求。

如上所述,防止有内存泄漏并尽可能快地释放所有内存是内存管理的重要组成部分。因为安全原因,在请求结束时, Zend 引擎会释放所有由上面提到的 API 所分配的内存。如果 PHP 使用 --enable-debug 配置选项进行构建,这将产生一个警告。

Example #1 PHP 的泄漏报警

ZEND_FUNCTION(leak)
{
    long leakbytes = 3;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &leakbytes) == FAILURE) {
        return;
    }

    emalloc(leakbytes);
}

以上例程的输出类似于:

[Thu Oct 22 02:14:57 2009]  Script:  '-'
/home/johannes/src/PHP_5_3/Zend/zend_builtin_functions.c(1377) :  Freeing 0x088888D4 (3 bytes), script=-
=== Total 1 memory leaks detected ===

Note当使用 PHP 变量时,需要确认变量的内存要使用 emalloc 来分配,并注意引用计数。相关细节请查看 变量的使用

Note内存泄漏检测仅可以发现由 emalloc 分配内存块导致的泄漏。为进行深层分析,建议使用内存检测器,如 valgrind 或 libumem 等。要简化此分析,可在 PHP 启动时通过设置环境变量 USE_ZEND_ALLOC=0 来禁用 PHP 的内存管理器。

相关文章
|
4月前
|
Java PHP
从引用计数到循环垃圾回收——解锁PHP高效内存管理的秘密
【8月更文挑战第2天】深入理解PHP中的垃圾回收机制
97 3
|
4月前
|
中间件 Shell PHP
|
6月前
|
设计模式 PHP 容器
在PHP中避免循环引用导致的内存泄漏问题
在PHP中避免循环引用导致的内存泄漏问题
|
7月前
|
缓存 PHP 数据库
【PHP开发专栏】PHP代码优化与内存管理
【4月更文挑战第30天】本文探讨了PHP的代码优化和内存管理,旨在提升Web应用性能。第一部分介绍了代码优化,包括减少代码重复、选择高效数据结构、减少函数调用、使用缓存、优化数据库查询、图像处理和正则表达式优化。第二部分讲解内存管理,建议减少全局变量、正确使用内存分配函数、利用对象引用计数、避免内存泄露及优化内存分配。第三部分通过在线论坛的缓存应用和图像处理的内存池技术展示了实践案例。
65 2
|
7月前
|
存储 缓存 算法
php遇到内存溢出
php遇到内存溢出
63 3
|
前端开发 API PHP
php内存溢出:Allowed memory size of 1342bytes exhausted (tried to allocate 8192 bytes)本地配置和宝塔配置解决方案
php内存溢出:Allowed memory size of 1342bytes exhausted (tried to allocate 8192 bytes)本地配置和宝塔配置解决方案
162 0
|
Java PHP
关于php递归函数内存溢出的问题
关于php递归函数内存溢出的问题
125 1
关于php递归函数内存溢出的问题
|
Java PHP
如何避免PHP中的内存泄漏问题?底层原理是什么?
如何避免PHP中的内存泄漏问题?底层原理是什么?
|
算法 Java PHP
PHP是如何操作内存的?底层原理是什么?
PHP是如何操作内存的?底层原理是什么?
149 0