ホームページ  >  記事  >  バックエンド開発  >  PHP変数のコピーオンライトメカニズム

PHP変数のコピーオンライトメカニズム

不言
不言オリジナル
2018-04-14 13:44:411374ブラウズ

この記事では、主に PHP 変数を使用したコピーオンライトの仕組みを紹介します。これは、必要な友人に参照してもらうために共有します。

プログラミングのアイデアを共有することもできます。 、しかし、言語間の違いは非常に明白ですが、ユーザーはその違いを理解することはプログラムを書いたりパフォーマンスを制御したりするのに役立ちます。 PHP の非常に重要なメカニズムであるコピー オン ライトを紹介しましょう。これについて説明する前に、著者はまず弱い型がどのように実装されるかを紹介します。

PHP が C で実装されていることは誰もが知っていますが、C は強く型付けされた言語です。どうすれば PHP が弱い型付け言語になるのでしょうか? C 言語の最下層の PHP 変数のコードを見てみましょう

typedef struct _zval_struct zval;
typedef unsigned int zend_uint;
ypedef unsigned char zend_uchar;
struct _zval_struct {
    zvalue_value value;      /*注意这里,这个里面存的才是变量的值*/
    zend_uint refcount__gc;  /*引用计数*/
    zend_uchar type;        /* 变量当前的数据类型 */
    zend_uchar is_ref__gc;   /*变量是否引用*/};typedef union _zvalue_value {    long lval;      /*PHP中整型的值*/
    double dval;    /*PHP的浮点数值*/
    struct {     
        char *val;        int len;
    } str;               /*PHP的字符串*/
    HashTable *ht;     /*数组*/
    zend_object_value obj;  /*对象*/} zvalue_value;

実際、PHP で使用する変数は下位レベルの構造体 zval であることがわかります。内部の zvalue_value 構造体は実際にはユニオンであり、このユニオンには実際に PHP の変数値が格納されます。以下では、実際の PHP コード例を使用して、上記の参照カウントに注目してください。まず C 言語について見てみましょう。最初は関数以外の部分です。関数部分については次の章で説明します

int i = 4;  //alloca方式在内存中分配空间,这个变量在内存中的栈区
int j = i;   //alloca方式在内存中分配空间,并且将原先内存空间里面的数据复制到新的内存空间中,这个变量在内存的栈区
int j = 5;  //不分配内存空间,对变量j所在的栈区空间的数据进行修改

PHP の部分を見てみましょう

PHPのすべての変数によって開かれるメモリ 一時変数でもグローバル変数でも空間はすべてヒープ内にありますが、PHPの一時変数はactive_symbal_tableテーブルに記録され、グローバル変数はsymbal_tableテーブルに記録されるのはなぜですか。 Cよりも遅いです。もっとたくさんのことをやってきたのに、ゆっくりしていられませんか?

  1. PHP が

  2. i のような変数に値を代入する場合、メモリのオーバーヘッドはありません。つまり、数万の値を代入しても、参照カウントは数万になるだけです。 . これとC言語は違います。変数の値が変更されると、このメカニズムはコピーオンライトメカニズムと呼ばれますPHP カーネルが int の値のオーバーフローを検出すると、メモリ空間が再度開かれます。整数型の範囲を超えると、自動的に float に変換されます。興味のある読者は自分で大きな整数を書くことができますが、float 値の範囲を超えて var_dump データ型が何であるかを確認することはできません。 最後の部分: PHP オブジェクト部分はデフォルトで参照モードになっているため、以下に示すように、割り当て後にオブジェクトのメンバー変数が変更された場合でも、コピーオンライトは有効になりません

    $i = 4;   //内核创建一个zval指针,并且为其以堆的方式开辟空间,让指针指向这个空间,将zval中的成员引用计数置为1,类型标记为整形,
    并且申请一个zvalue_value指针,同样以堆的方式以其开辟空间,同时将该联合体中的lval赋值为4,并且在symbal_table的hash表中记录变量i和zval指针的映射关系
    $j = $i;   //没有在申请内存空间,在zval的成员中引用计数标记为
    2$j = 5;   //内核重新创建zval指针,重复下上面的步骤,我就不重复说明了,重点是将旧的zval引用计数标记为1

    関連する推奨事項:

PHP変数リファレンス 非リファレンスとの性能比較

PHP変数置換方法例まとめ

以上がPHP変数のコピーオンライトメカニズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。