为什么引用计数是 2 而不是 1?

发布于 2024-10-03 06:17:15 字数 296 浏览 0 评论 0原文

  $var = 1;
  debug_zval_dump($var);

输出:

long(1) refcount(2)


  $var = 1;
  $var_dup = &$var;
  debug_zval_dump($var);exit;

输出:

long(1) refcount(1)

更新

对答案非常失望......

  $var = 1;
  debug_zval_dump($var);

Output:

long(1) refcount(2)


  $var = 1;
  $var_dup = &$var;
  debug_zval_dump($var);exit;

Output :

long(1) refcount(1)

UPDATE

Very disapointed at the answer...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

停滞 2024-10-10 06:17:15

void debug_zval_dump (混合 $variable );


代码

$var = 1;              # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.

输出

long(1) refcount(2)

解释
由于 $var 的引用计数为 1,PHP 对此进行了优化并直接处理内存而不是制作副本,因为不会污染任何其他引用。 PHP 在内部通过引用传递 $var,以便它可以在需要时直接编辑内存。第二个引用是在实际调用 debug_zval_dump() 时创建的。

这里,重新计数 2 是非常不明显的。那么发生了什么事?

当变量具有单个引用时(就像 $var 在用作 debug_zval_dump() 的参数之前一样),PHP 引擎会优化将其传递给函数的方式。在内部,PHP 将 $var 视为引用(因为该函数的范围增加了引用计数),但需要注意的是,如果传递的引用碰巧被写入,则会创建一个副本,但仅在写入时进行。这称为“写入时复制”。

因此,如果 debug_zval_dump() 碰巧写入了它的唯一参数(但事实并非如此),那么就会创建一个副本。在此之前,参数仍然是引用,导致函数调用范围内的引用计数增加到 2。


代码

$var = 1;              # $var's Refcount = 1
$var_dup = &$var;      # $var's Refcount = 2
debug_zval_dump($var); # A copy is passed as $var's refcount is 2.

输出

long(1) refcount(1)

解释
这次,当调用该函数时,将创建 $var 的副本。这是因为 $var 被引用了两次,并且 PHP 不想污染任何其他引用,因此它会复制 $var 以便自己处理。由于现在有一块单独的内存仅用于函数调用的范围,因此它只有一个引用,即 self。因此,对于函数的范围,副本的引用计数为 1(它是自身)。

void debug_zval_dump ( mixed $variable );


Code:

$var = 1;              # $var's Refcount = 1
debug_zval_dump($var); # $var is passed by refrence intarlly.

Output:

long(1) refcount(2)

Explanation:
As $var's refcount is 1, PHP optimizes this and handles the memory directly instead of making a copy because there is no chance of contaminating any other references. PHP internally passing $var by reference, so that it can edit the memory directly if it needs too. The second reference is created when actually calling debug_zval_dump().

A refcount of 2, here, is extremely non-obvious. So what's happening?

When a variable has a single reference (as did $var before it was used as an argument to debug_zval_dump()), PHP's engine optimizes the manner in which it is passed to a function. Internally, PHP treats $var like a reference (in that the refcount is increased for the scope of this function), with the caveat that if the passed reference happens to be written to, a copy is made, but only at the moment of writing. This is known as "copy on write."

So, if debug_zval_dump() happened to write to its sole parameter (and it doesn't), then a copy would be made. Until then, the parameter remains a reference, causing the refcount to be incremented to 2 for the scope of the function call.


Code:

$var = 1;              # $var's Refcount = 1
$var_dup = &$var;      # $var's Refcount = 2
debug_zval_dump($var); # A copy is passed as $var's refcount is 2.

Output:

long(1) refcount(1)

Explanation:
This time a copy of $var is being made when the function is called. This is because $var is referenced twice and PHP does not want to contaminate any other references so it makes a copy of $var for it's self to work on. As there is now a separate piece of memory that is only used for the scope of the function call it only has one refrence, it's self. So for the scope of the function the copy's refcount is 1 (it's self).

月下客 2024-10-10 06:17:15

我认为此方法的文档在“注意引用计数”部分下对此进行了解释:

debug_zval_dump

I think the documentation for this method explains this under the section "Beware the Ref Count":

debug_zval_dump

吻泪 2024-10-10 06:17:15

代码

$var = 1;
debug_zval_dump($var);

输出long(1) refcount(2)

解释:当变量有单个引用时,与 $var 在用作 debug_zval_dump() 的参数之前一样,PHP 引擎优化了它传递给函数的方式。 PHP 基本上创建一个指向变量的指针,并且在内部,PHP 将 $var 视为引用,因此它的引用计数会针对此函数的范围而增加。

代码

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

输出long(1) refcount(1)

解释:这里$var变量是写入时复制,创建该变量的全新单独实例,并且因为 debug_zval_dump 正在处理$var 的全新副本,不是引用,它的引用计数为 1。一旦函数完成,副本就会被销毁。

希望能澄清这一点。

Code:

$var = 1;
debug_zval_dump($var);

Output: long(1) refcount(2)

Explanation: When a variable has a single reference, as did $var before it was used as an argument to debug_zval_dump(), PHP's engine optimizes the manner in which it is passed to a function. PHP, basically makes a pointer to the variable and internally, PHP treats $var like a reference and so it's refcount is increased for the scope of this function.

Code:

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

Output: long(1) refcount(1)

Explanation: Here the $var variable is copyied on write, making whole new seprate instance of that varable and because debug_zval_dump is dealing with a whole new copy of $var, not a reference, it's refcount is 1. The copy is then destroyed once the function is done.

Hope that clears it up.

梦里泪两行 2024-10-10 06:17:15

我将尝试为 debug_zval_dump() 函数以及处理变量的方式提供更多说明。如果我错了,请不要杀了我:)...

  $var = 1;
  debug_zval_dump($var);

我认为调试函数会计算 $var refcount(1) 和 1 refcount(2),因为 1 是 的值>$var
如果你从逻辑上看,你实际上是在说这个。

  1 = 1;
  debug_zval_dump(1);

第二部分:

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

您在这里看到的是,您将 $var 设置为 $var_dup 但保留其值。 $var 的引用计数为 1,因为您将其“链接”到 $var_dup

$var = 2;
$var_dup = &$var; //or $var = &$var_dup; (doesn't matter which one)
$var = 3;
debug_zval_dump($var_dup);exit;

这给出了long(3) refcount(1)...为什么它的refcount是1?正如您所看到的,$var_dup 的值从未被分配为 3,它应该是 2,对吧?不,不应该,因为您使用 &$var 使其保持最新。这意味着当您在 $var = 3debug_zval_dump($var_dup);exit; 之间经过 $var = 4 时,$var_dup 的值将自动更新,因为您已链接它们,使其成为 1 引用计数。

然后还有另一个情况:

$var = 2;
$var_dup = $var;
$var = 4;
debug_zval_dump($var_dup);exit;

它的输出是:long(2) refcount(2)
正如您所看到的,$var_dup 的值是正确的。 $var 是 2,该值通过 $var_dup 传递,他坚持使用它。引用计数为 2,因为它计数 $var = 4;$var_dup = $var;
当我们删除 $var = 4; 时,我们得到:

$var = 2;
$var_dup = $var;
debug_zval_dump($var_dup);exit;

其输出为:long(2) refcount(3)
现在,调试函数计算以下内容:$var_dup(1)、=$var(2)(因为 $var_dup 源自 $var)和 $var(= 2;)(3)。

我希望你明白我的意思。在我看来,这更多的是数学而不是编程,所以这可能是它是一个难以理解的函数的原因。

再说一次,如果我错了,请不要杀我:)...
您好,
Mixxiphoid

免责声明
我不知道这个功能的目的是什么。事实上直到今天我才听说过它。所以我不对不当使用负责:)。

I'll try to give some more light to the debug_zval_dump() function and the way you process your variables. Don't kill me if I'm wrong :)...

  $var = 1;
  debug_zval_dump($var);

I think the debug function counts the $var refcount(1) and the 1 refcount(2) since 1 is the value of $var.
If you look at it logically you are actually saying this.

  1 = 1;
  debug_zval_dump(1);

Second part:

$var = 1;
$var_dup = &$var;
debug_zval_dump($var);exit;

What you see here is that you set $var to $var_dup but is keeping its value. The refcount of $var is 1 because you 'linked' it to $var_dup.

$var = 2;
$var_dup = &$var; //or $var = &$var_dup; (doesn't matter which one)
$var = 3;
debug_zval_dump($var_dup);exit;

This gives long(3) refcount(1)... Why is it refcount 1? As you can see the value of $var_dup was never assigned to 3, it should be 2 right? No it shouldn't because you keep it up to date with &$var. This means that when you past $var = 4 between $var = 3 and debug_zval_dump($var_dup);exit; the value of $var_dup will be updated automatically because you have linked them, making it 1 refcount.

Then there is this other occurrence:

$var = 2;
$var_dup = $var;
$var = 4;
debug_zval_dump($var_dup);exit;

The output of this is: long(2) refcount(2).
As you can see the value of $var_dup is correct. $var was 2, the value was passed through $var_dup an he sticked with it. The refcount is 2 because is counts $var = 4; and $var_dup = $var;.
When we remove the $var = 4; we get this:

$var = 2;
$var_dup = $var;
debug_zval_dump($var_dup);exit;

The output of this is: long(2) refcount(3).
Now the debug function count the following: $var_dup(1), =$var(2) (since $var_dup was originated from $var) and $var(= 2;)(3).

I'll hope you understand what I mean. In my opinion this is more math then programming, so that may be the reason why it is a difficult function to understand.

And again, if I'm wrong, don't kill me :)...
Greetings,
Mixxiphoid

Disclaimer
I do not know what the purpose is of this function. I actually never heard of it until today. So I'm not responsible for inappropriate use :).

居里长安 2024-10-10 06:17:15

这里,重新计数 2 是非常不明显的。特别是考虑到上面的例子。那么发生了什么事?

当变量具有单个引用时(就像 $var1 在用作 debug_zval_dump() 的参数之前一样),PHP 引擎会优化将其传递给函数的方式。在内部,PHP 将 $var1 视为引用(因为该函数的范围增加了引用计数),但需要注意的是,如果传递的引用碰巧被写入,则会创建一个副本,但仅在写入时进行。这称为“写入时复制”。

因此,如果 debug_zval_dump() 碰巧写入了它的唯一参数(但事实并非如此),那么就会创建一个副本。在此之前,参数仍然是引用,导致函数调用范围内的引用计数增加到 2。

-- 积分请参阅 php 手册。阅读该函数附带的完整描述,您甚至应该问过它。

- - 编辑:
糟糕,我应该在回答之前阅读更多评论:D 无论如何,这是前面提到的问题的答案。

A refcount of 2, here, is extremely non-obvious. Especially considering the above examples. So what's happening?

When a variable has a single reference (as did $var1 before it was used as an argument to debug_zval_dump()), PHP's engine optimizes the manner in which it is passed to a function. Internally, PHP treats $var1 like a reference (in that the refcount is increased for the scope of this function), with the caveat that if the passed reference happens to be written to, a copy is made, but only at the moment of writing. This is known as "copy on write."

So, if debug_zval_dump() happened to write to its sole parameter (and it doesn't), then a copy would be made. Until then, the parameter remains a reference, causing the refcount to be incremented to 2 for the scope of the function call.

-- Credits go to the php manual. Read the whole description that comes with the function and you should've even has asked it.

--- Edit:
Woops, I should read more comments before answering :D Anyways, this is the answer to the question as mentioned before.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文