php之内存管理基础-阿里云开发者社区

开发者社区> 微个日光日> 正文

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 的内存管理器。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java 简介(Java 发展概述)|学习笔记
快速学习 Java 简介(Java 发展概述)
5 0
Java 程序基本概念(注释)|学习笔记
快速学习 Java 程序基本概念(注释)
4 0
方法的定义与使用(方法的基本定义)|学习笔记
快速学习 方法的定义与使用(方法的基本定义)
3 0
Java 程序基本概念(标识符与关键字)|学习笔记
快速学习 Java 程序基本概念(标识符与关键字)
3 0
CLASSPATH 环境属性|学习笔记
快速学习 CLASSPATH 环境属性
3 0
快速搭建LAMP环境
CentOS 7.7的ECS实例(云服务器)。通过本教程的操作,您可以基于ECS实例快速搭建一套LAMP环境。
31 0
Java 简介(Java 主要特点)|学习笔记
快速学习 Java 简介(Java 主要特点)
4 0
Java 数据类型划分(布尔型)|学习笔记
快速学习 Java 数据类型划分(布尔型)
4 0
云起冬季实战营第一期学习报告
冬奥云小宝带你玩转五期实战营 覆盖五大技术方向 “0成本”实践学习 快速晋级为专业的“云上开发者”
6 0
175
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载