【问题标题】:Is this a php memory leak?这是php内存泄漏吗?
【发布时间】:2013-11-12 01:19:45
【问题描述】:

更新我注意到,使用特定的 require_once('myobject.php') 会显示内存增加。这个 require_once() 是有条件地运行的。当我将 require_once() 语句从 if 语句中移出以便它一直加载时,内存增加就消失了。对我来说没有意义,但问题已经解决了。我不确定这实际上是一个“答案”,所以我不会回答它。

我的页面页脚中有memory_get_usage(),每次刷新页面时,我都会看到它每次增加约 100k。我的页面加载创建了许多对象并在完成后销毁它们。我的父对象每个都有__destruct(),它使用unset() 和所有子对象。具有对父对象的引用的子对象具有__destruct()unset() 这些引用。

在处理我的页面的不同部分之前和之后插入memory_get_usage() 只会告诉我由于脚本的该部分而添加了多少总使用量。在页面完成加载后,如何确定哪些内存丢失并且没有被回收用于垃圾收集?

我有一个包含存储用户信息的对象的全局 $_SESSION var,但已使用 strlen(serialize($object)) 验证该对象的大小没有增长。

我认为我看到的是内存泄漏,并且 php 垃圾收集应该在脚本结束后生效。有什么想法可以调试吗?

【问题讨论】:

  • 如果我错了,有人可以纠正我,但如果你有标准的 Apache 和 PHP 设置,PHP 进程会在请求完成后被销毁,因此它不会在请求之间使用内存。所以unset() 无关紧要(跨请求)。这对于 php-fpm 可能会有所不同,我不确定。但很可能没有内存泄漏,但可能某些会话文件的大小增加了,因此下次加载时会变大。
  • @Matt 你为什么不把它作为答案发布,这本来是一个很好的答案。
  • 当然,我认为我的答案可以详细说明,但我现在将其发布为起点。
  • 像 APC 这样的字节码缓存不喜欢有条件的包含/要求;这很可能是内存使用量增加的根本原因。很大程度上取决于缓存的确切实现,例如 - 缓存所有代码路径(即解析包含和不包含的文件并缓存两个路径) - 根本不缓存 - ...缓存非常困难。无论哪种方式,关键是,对我来说,这听起来可能与字节码缓存有关。

标签: php memory-leaks


【解决方案1】:

如果我错了,有人可以纠正我,但如果你有标准的 Apache 和 PHP 设置,PHP 进程会在请求完成后被销毁,因此它不会在请求之间使用内存。

所以unset()__destruct() 等无关紧要(跨请求)。当 PHP 进程结束时,所有内存都被回收。

但很可能没有内存泄漏,但可能某些会话文件的大小增加了,因此下次加载时它会更大。

注意:这对于 php-fpm 可能有所不同,我不确定。

【讨论】:

  • 感谢您的意见。我注意到使用特定的require_once('myobject.php') 会显示内存增加。这个require_once() 是有条件地运行的。当我将 require_once()statement 从 if 语句中移出以便它一直加载时,内存增加就消失了。这有意义吗?
  • 我不知道条件是什么。或者是每次都发生内存的增加,还是只有在满足这个未知条件时才会增加。 N 次重新加载后内存是否无限增加(其中 N 至少...10、20、100)?
  • 每次重新加载都会增加 80k 到 150k,但我从未找到限制 - 尽管我只尝试了 30 次。
  • 那么不确定。据我所知,myobject.php 加载一个文件,读取它,并向其中附加大约 100k 的数据。或者更有可能在$_SESSION 中存储更多数据。
  • 包含 myobject.php 没有运行任何代码,奇怪的是它只发生在条件包含中。无论哪种方式都包含相同的代码。可能不值得担心 - 我将只包含代码并保留它。感谢您的帮助 - 即使没有解决问题,您的回答也有助于更好地理解流程。
猜你喜欢
  • 2011-02-20
  • 2013-08-12
  • 2013-01-08
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多