Confusion about PHP 7 refcount
Asked Answered
D

1

12
<?php

$s = "foobar";

$t = $s;

$u = $s;

echo PHP_VERSION . "\n";

debug_zval_dump($s);

xdebug_debug_zval('s');

Run in PHP 5.6.16

php 5 refcount

Run in PHP 7.0.2

php 7 refcount

I think the result (PHP 7) should be:

string(6) "foobar" refcount(4)
s: (refcount=3, is_ref=0)="foobar"

I wonder what makes the difference? Need some explanation. Thanks a lot.

------ update ------

Nikita Popov's - PHP 7 – What changed internally? (P41)

http://www.slideshare.net/nikita_ppv/php-7-what-changed-internally

slideshare

Decided answered 13/1, 2016 at 10:23 Comment(10)
php.net/manual/en/features.gc.refcounting-basics.phpPhaih
@Phaih It's php 5.xDecided
nothing changed in both.. conceptualPhaih
@Phaih why refcount is 0?Decided
@Phaih it's 3 in php 5.xDecided
ref count either 0 or 1, its part of reference set 0 1 indicate either part of or not... anyway i am not the downvoter.... and i suggest to downvoter plz recommend the improvements.Phaih
actually u can ask why refcount is 0 ... its valid question... bro..Phaih
nikic.github.io/2015/05/05/…Burglarious
@Burglarious slideshare.net/nikita_ppv/php-7-what-changed-internally P41 says 3.Decided
PHP7 seems to distinguish between value types that are refcounted and the ones that aren’t. It seems strings are refcounted sometimes. String literals (“interned strings”) aren’t (and probably don’t reside on the heap) which is why you get 0. Also, these debug methods don’t seem to be particularly well updated for PHP 7 or they would output the info from the type_info field in a zval.Tortoise
B
15

In PHP 7 a zval can be reference counted or not. There is a flag in the zval structure which determined this.

There are some types which are never refcounted. These types are null, bool, int and double.

There are other types which are always refcounted. These are objects, resources and references.

And then there are types, which are sometimes refcounted. Those are strings and arrays.

For strings the not-refcounted variant is called an "interned string". If you're using an NTS (not thread-safe) PHP 7 build, which you typically are, all string literals in your code will be interned. These interned strings are deduplicated (i.e. there is only one interned string with a certain content) and are guaranteed to exist for the full duration of the request, so there is no need to use reference counting for them. If you use opcache, these strings will live in shared memory, in which case you can't use reference counting for them (as our refcounting mechanism is non-atomic). Interned strings have a dummy refcount of 1, which is what you're seeing here.

For arrays the not-refcounted variant is called an "immutable array". If you use opcache, then constant array literals in your code will be converted into immutable arrays. Once again, these live in shared memory and as such must not use refcounting. Immutable arrays have a dummy refcount of 2, as it allows us to optimize certain separation paths.

Badger answered 13/1, 2016 at 16:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.