猿问

诊断内存泄漏 - 允许#bytes的内存大小耗尽

诊断内存泄漏 - 允许#bytes的内存大小耗尽

我遇到了可怕的错误消息,可能通过艰苦的努力,PHP内存不足:

在第123行的file.php中,####字节的允许内存大小耗尽(尝试分配####字节)

增加限制

如果您知道自己在做什么并希望增加限制,请参阅memory_limit

ini_set('memory_limit', '16M');ini_set('memory_limit', -1); // no limit

谨防!你可能只是解决症状而不是问题!

诊断泄漏:

错误消息指向一条带有循环的行,我认为该循环正在泄漏或不必要地累积内存。我memory_get_usage()在每次迭代结束时打印语句,可以看到数字慢慢增长,直到达到极限:

foreach ($users as $user) {
    $task = new Task;
    $task->run($user);
    unset($task); // Free the variable in an attempt to recover memory
    print memory_get_usage(true); // increases over time}

对于这个问题的目的,让我们假设最坏的面条代码可以想象在全球范围内的某处藏匿在$userTask

什么工具,PHP技巧或调试巫毒可以帮助我找到并解决问题?


侃侃无极
浏览 444回答 3
3回答

PIPIONE

php中有几个可能的内存泄漏点:php本身php扩展你使用的PHP库你的PHP代码没有深度逆向工程或php源代码知识,很难找到并修复前3个。对于最后一个,您可以使用二进制搜索内存泄漏代码和memory_get_usage

江户川乱折腾

这是我们用来确定哪些脚本在我们的服务器上使用最多内存的技巧。将以下代码段保存在文件中,例如/usr/local/lib/php/strangecode_log_memory_usage.inc.php:<?phpfunction&nbsp;strangecode_log_memory_usage(){ &nbsp;&nbsp;&nbsp;&nbsp;$site&nbsp;=&nbsp;''&nbsp;==&nbsp;getenv('SERVER_NAME')&nbsp;?&nbsp;getenv('SCRIPT_FILENAME')&nbsp;:&nbsp;getenv('SERVER_NAME'); &nbsp;&nbsp;&nbsp;&nbsp;$url&nbsp;=&nbsp;$_SERVER['PHP_SELF']; &nbsp;&nbsp;&nbsp;&nbsp;$current&nbsp;=&nbsp;memory_get_usage(); &nbsp;&nbsp;&nbsp;&nbsp;$peak&nbsp;=&nbsp;memory_get_peak_usage(); &nbsp;&nbsp;&nbsp;&nbsp;error_log("$site&nbsp;current:&nbsp;$current&nbsp;peak:&nbsp;$peak&nbsp;$url\n",&nbsp;3,&nbsp;'/var/log/httpd/php_memory_log');}register_shutdown_function('strangecode_log_memory_usage');通过在httpd.conf中添加以下内容来使用它:php_admin_value&nbsp;auto_prepend_file&nbsp;/usr/local/lib/php/strangecode_log_memory_usage.inc.php然后分析日志文件&nbsp;/var/log/httpd/php_memory_log您可能需要touch /var/log/httpd/php_memory_log && chmod 666 /var/log/httpd/php_memory_log在Web用户可以写入日志文件之前。
随时随地看视频慕课网APP
我要回答