【发布时间】:2020-05-09 05:51:03
【问题描述】:
我的 PHP 脚本出现“内存耗尽”。我不知道为什么。限制为 128Mb。我正在从 javascript xmlrequest() 发送一个最大为 10MB(通常小于 1MB)的 json 字符串。 PHP 脚本本身是 43K。即使将所有内容复制十几次,我也不应该耗尽内存。我在 getParentFolders() 对数据库进行了几次调用,但只产生了几行。当然不是它声称我正在使用的 62 兆字节。我使用了 Xdebug(见图),但这并没有告诉我任何有用的信息,只是,是的,我使用了很多内存。
因此,在这一点上,我正在尝试执行“最佳实践”以最大程度地减少内存使用量。一个简单的解决方法,或者我认为,是通过引用传递值。所以我在每个函数的每个变量之前都放了一个“&”。令我惊讶的是,内存消耗没有变化。事实上,它稍微差了几个字节。我也尝试过将每个变量都用作全局变量,但再次令我惊讶的是,差别不大。
那么发生了什么?为什么通过引用传递和使用全局变量不会产生我预期的性能优势? (见图片)
Xdebug '传值'
Xdebug '通过引用'
请注意,它们几乎完全相同。
对于那些想要代码的人,这里是 getParentFolders() 函数,它只返回一个短字符串,但不知何故使用了 70Mb!
function getParentFolders(&$node) { //returns a string of folders
debugprint("GetParentFOlders()"); //prints if $DEBUG flag is on
$parent = getParent($node);
$path = "";
while ($parent) { //goes till we hit root folder
$path = $parent->title . '/' . $path; //prepend it
$parent = getParent($parent);
}
return $path;
}
function getParent(&$node) { //return node that is the parent
global $email;
$parentId = $node->parentId;
$clientId = $node->parentClient;
$idCol = $clientId . "_id";
$tablename = $email . "_bookmarks";
$query = "SELECT * FROM `$tablename`
WHERE $idCol = '$parentId'"; //only return one row since id is unique
$result = sendquery($query);
return (object) $result[0];
}
编辑:
澄清一下,我正在寻找关于 PHP 内存使用和最佳实践的技术解释 - 特别是为什么我没有看到内存差异 - 这不是解决问题的方法。
【问题讨论】:
-
PHP 和大多数语言都使用垃圾回收。函数完成时不能保证释放权利。是什么让您认为字符串是问题所在?问题可能出在 sendquery 中的某个地方,或者可能是 getParent 被调用了多少次。
-
可能是数据中的循环引用导致代码中的无限循环。你的根节点有自己的父节点吗?
标签: php memory memory-management out-of-memory pass-by-reference