PHP分配的内存在单个请求结束时总是被释放吗?

6
我对PHP中的内存泄漏有些困惑。
我读到过PHP通过Zend内存管理器自动释放每个请求中使用的内存: http://www.webreference.com/programming/php_mem/2.html 但是我看到很多人和话题(甚至在SO上)都关注PHP和内存泄漏。
所以我觉得我可能错过了什么。 在不同的请求之间,PHP是否可能存在内存泄漏?
1个回答

8

在使用默认的Apache配置时,PHP脚本在不同请求之间不可能出现内存泄漏,因为一个请求中使用的变量和代码在该请求结束时被释放,PHP的内存分配器会为下一个请求重新启动。然而,PHP解释器或扩展中的错误可能会导致内存泄漏。

更大的问题是Apache子进程内部有PHP的内存空间。它们会膨胀以分配PHP脚本的峰值内存使用量,然后保持这个内存分配直到子进程被杀死(一旦进程请求内核分配一部分内存,该内存就不会在进程死亡之前释放)。关于为什么这是一个问题以及如何解决它的更详细的解释,请参见我在Server Fault上的答案。

脚本中的内存泄漏,即变量未被取消设置,且PHP垃圾回收器失败的情况非常罕见——大多数PHP脚本运行几百毫秒,这通常不足以使严重的内存泄漏显现。

你可以使用memory_get_usage()memory_get_peak_usage()来监控PHP脚本使用的内存量 - 在PHP手册中也有关于内存使用和如何进行编程防御的详细解释。 这篇文章详细介绍了PHP的内存管理。 编辑: 你可以使用httpd -l来确定Apache的编译模块 - 默认值因操作系统分发和仓库配置而异。有很多方法将PHP与Apache接口 - 最详细的在这里

1
@Andy Apache不会为每个请求创建一个新进程。实际上,出于性能考虑,进程会被重复使用一定次数。请参阅MaxRequestsPerChild - Arnaud Le Blanc
@arnaud576875 这个指令与 Apache 子进程相关,而不是 PHP 进程。 - Andy
@Andy PHP本身不会创建进程(除非您使用FastCGI或php-fpm,但这似乎不是您所说的Apache分叉的情况)。作为Apache模块的PHP只是存在于Apache进程中的代码。 - Arnaud Le Blanc
1
这仍然是错误的,Apache 不管理 PHP 的内存。如果 PHP 在请求期间执行了 malloc() 但没有执行 free(),则分配的内存将在 Apache 进程的生命周期中泄漏。 - Arnaud Le Blanc
让我们在聊天中继续这个讨论 - Andy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接