php 7ごみ回収メカニズムの浅い分析


今日はもともとphpのごみ回収メカニズムを理解しようと思っていたが、phpマニュアルの説明を見て、ごみ回収メカニズムの原理を大体理解して、自分でコードを書いてテストしようと思っていたが、マニュアルの言うことと同じではないかと思った.そしてこの文章がありました.
問題を発見する
マニュアルの実例コードに従ってノックして、不思議な問題を発見しましたが、結果は違いますね.
$a = "new String";
xdebug_debug_zval( 'a' );

マニュアルは、次の結果を示しています.
a: (refcount=1, is_ref=0)='new string'

自分の結果:
a: (interned, is_ref=0)='new String'

これは何ですか.私のPHPバージョンは7.1だったが、マニュアルには5.3だった.では、PHP7がごみ回収メカニズムを最適化していることがわかりました.もし私が大牛だったら、ソースを見に行きます.残念ながら私は違います.だから私达は资料を调べるしかなくて、半日探して、多くのタイトルがPHP 7のごみの回収のメカニズムの文章であることを発见して、しかし中の内容は确かにPHP 5のごみの回収のメカニズムの内容で、あるいは直接ソースコードに行きます!これ...ソースが読めたら、コピーする必要がありますか?たゆまぬ捜索を経て、この文章を見つけた--PHP 7におけるzvalの変化
問題を解決する 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. PHP 7では、zval構造体にzvalが参照されてカウントできるかどうかを決定するフラグがある.null,bool,int,doubleのような変数タイプは永遠に参照カウントされない(この場所はあまり厳密ではないかもしれないが、鳥兄のブログにはPHP 7のzvalのタイプは18種類あり、そのうちIS_LONG、IS_DOUBLE、IS_NULL、IS_FALSE、IS_TRUEは参照カウントを使用しないと書かれている).object、resources、referencesのような変数タイプでは、常に参照カウントが使用されます.しかし、arrayのようにstringsのような変数タイプでは参照カウントが使用される場合があり、できない場合があります.参照カウントを使用しない文字列タイプを「interned string(文字列を保持)」と呼びます.NTS(非スレッドセキュリティ)のPHP 7を使用して構築する場合は、通常、コード内のすべての文字列文字が限定されます.これらの予約文字列は重複できません(すなわち、特定のコンテンツを含む予約文字列が1つしか存在しません).リクエストが終了するまで破棄されないため、参照カウントを行う必要はありません.opcacheを使用すると、保持文字が共有メモリに格納されます.この場合、参照カウントは使用できません(カウントのメカニズムが非原子であるため).保持文字列の擬似参照数は1です.配列の場合、参照カウントのない変数を「可変配列」と呼びます.opcacheを使用すると、コードの定数配列文字が可変配列に変換されます.同様に、共有メモリに存在するため、参照カウントは使用できません.可変配列の擬似参照数は2です.これは、いくつかの分離パスを最適化できるためです.
まとめ
PHP 7のゴミ回収メカニズムは最適化されています.PHPのゴミ回収メカニズムを聞かれたとき、マニュアルで説明したように答えるのではなく、バージョン別に説明しなければなりません.もちろん、この記事はPHP 7のzvalの変化を簡単に説明しただけで、PHP 7のゴミ回収機制を深く説明することはできません.主な原因はやはり私达の技术のレベルがまだ向上しなければならないので、ソースコードはその部分の见る云の中の雾の中を解釈して、更に多くの时間を要して勉强して、后で理解してからこの穴を埋めにくるでしょう.この文章は主にmarkを作る.もちろん能力のある大人にも見てもらいたいので、教えてください.
参考資料
PHP 7におけるzvalの変化