Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/239.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-为什么引用传递使用相同的内存量?_Php_Memory_Memory Management_Out Of Memory_Pass By Reference - Fatal编程技术网

PHP-为什么引用传递使用相同的内存量?

PHP-为什么引用传递使用相同的内存量?,php,memory,memory-management,out-of-memory,pass-by-reference,Php,Memory,Memory Management,Out Of Memory,Pass By Reference,我的PHP脚本中“内存耗尽”。我不明白为什么。限制为128Mb。我正在从javascript xmlrequest()发送一个最大为10MB(通常低于1MB)的json字符串。PHP脚本本身是43K。即使把所有东西都复制了十几遍,我也不应该把内存用完。我在getParentFolders()上对数据库进行了一些调用,但只生成了几行。当然不是它声称我正在使用的62兆字节。我曾经使用过Xdebug(见图),但这并没有告诉我什么有用的东西,只是说是的,我使用了大量内存 因此,在这一点上,我试图做“最佳

我的PHP脚本中“内存耗尽”。我不明白为什么。限制为128Mb。我正在从javascript xmlrequest()发送一个最大为10MB(通常低于1MB)的json字符串。PHP脚本本身是43K。即使把所有东西都复制了十几遍,我也不应该把内存用完。我在getParentFolders()上对数据库进行了一些调用,但只生成了几行。当然不是它声称我正在使用的62兆字节。我曾经使用过Xdebug(见图),但这并没有告诉我什么有用的东西,只是说是的,我使用了大量内存

因此,在这一点上,我试图做“最佳实践”,以尽量减少内存使用。一个简单的解决方法,或者我认为,就是通过引用传递值。所以我在每个函数的每个变量前面加了一个&。令我惊讶的是,内存消耗没有变化。事实上,它稍微差了几个字节。我也尝试过使用每个变量作为全局变量,但令我惊讶的是,它们之间没有什么区别

发生了什么事?为什么通过引用传递和使用globals不能产生我期望的性能优势?(见图片)

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内存使用和最佳实践的技术解释——特别是为什么我没有看到内存差异——这不是解决问题的方法。

使用
LIMIT 1
确保查询结果返回一行;如果未找到结果,则使
getParent()
返回
false
null
,以便可以将其设置为
$parent
以退出
循环。我不认为您需要在本例中通过引用传递
$node
参数。

使用
限制1确保查询结果返回一行;如果未找到结果,则使
getParent()
返回
false
null
,以便可以将其设置为
$parent
以退出
循环。我不认为您需要通过引用来传递
$node
参数。

在您的例子中,
$node
的值是一个引用,即指向对象的指针。在PHP5+中,“对象”不是直接的值。您总是通过指向对象的指针来处理对象:当您执行
newclassname
时,它的计算结果是指向对象的指针;当您使用
->
操作符时,它会获取指向左侧对象的指针

因此,如果这两个函数都是按值传递的,那么传递的对象的大小就是指针的大小。当您通过引用传递时,这基本上将指针封装在另一个级别的指针中,该级别的指针大小相同(尽管由于有两个指针,所以总内存更大)。通过引用传递的唯一一点是,它允许您在函数中分配给
$node
,以指向不同的对象或持有不同类型的值,并将其反映在调用函数中传递的变量中,但您不会在此处的任何位置分配给
$node
(修改指向
$node
的对象的字段与指定给
$node
不同),因此这里按引用传递没有意义


(此外,即使您传递了一个值类型,如PHP中的数组,它们也具有写时复制语义,并且在您向其写入之前不会被复制。即使您向其写入并使其进行复制,该复制也只会持续此局部变量的生命周期,该生命周期在函数末尾结束,因此不会产生持久的内存使用。)节点的值是一个引用,即指向对象的指针。在PHP5+中,“对象”不是直接的值。您总是通过指向对象的指针来处理对象:当您执行
新建类名
时,它将计算为指向对象的指针;当您使用
->
运算符时,它将获取指向左侧对象的指针

因此,如果这两个函数都是按值传递的,那么传递的对象的大小就是指针的大小。当通过引用传递时,这基本上将指针封装在另一个级别的指针中,该级别的指针大小相同(尽管由于有两个指针,所以总内存更大)。通过引用传递的唯一一点是,它允许您在函数中分配给
$node
,以指向不同的对象或持有不同类型的值,并将其反映在调用函数中传递的变量中,但您不会在此处的任何位置分配给
$node
(修改指向
$node
的对象的字段与指定给
$node
不同),因此这里按引用传递没有意义


(此外,即使您传递了一个值类型,如PHP中的数组,它们也具有写时复制语义,并且在您向其写入之前不会被复制。即使您向其写入并使其进行复制,该复制也只会持续此局部变量的生命周期,该生命周期在函数末尾结束,因此不会产生持久的内存使用。)

答案是对象不能按值传递。它们总是按引用传递。“按引用传递”操作符“&”除了将对象引用(即指针)包装在包装器中,然后传递新指针外,不会做任何其他事情


至于内存使用情况,除了数据库查询结果似乎带来了大量开销之外,没有简单的答案,您希望留下“足迹”(即从数据库返回的任何结果或任何变量)尽可能小。

答案是对象不能按值传递。它们总是按引用传递。“按引用传递”操作符、&'就可以了