zoukankan      html  css  js  c++  java
  • phpCOW机制详解

    写时复制(Copy-on-Write,也缩写为COW),顾名思义,就是在写入时才真正复制一份内存进行修改。 COW最早应用在*nix系统中对线程与内存使用的优化,后面广泛的被使用在各种编程语言中,如C++的STL等。 在PHP内核中,COW也是主要的内存优化手段。 在前面关于变量和内存的讨论中,引用计数对变量的销毁与回收中起着至关重要的标识作用。 引用计数存在的意义,就是为了使得COW可以正常运作,从而实现对内存的优化使用。

     

    写时复制的作用

    以下是一段代码:

    <?php

    var_dump(memory_get_usage());//先打印出当前内存情况

    $arr = array_fill(0, 100000, 'tioncico');//生成一个0-100000键的数组

    var_dump(memory_get_usage());//打印内存

    $arr_copy = $arr;//把数组赋值给另一个

    var_dump(memory_get_usage());//打印内存

    $j=1;

    foreach($arr_copy as $i) {//循环遍历该数组键值查看内存情况

        $j += count($i);

    }

    var_dump(memory_get_usage());//打印内存

    也就是说,就算我们不使用引用,php变量在传值,赋值的情况,都是指向同一个内存,但是如果当$arr_copy的值改变了会怎么样呢?<?php

    var_dump(memory_get_usage());

    //$tipi = array_fill(0, 3, 'php-internal');

    //不用array_fill的原因可自己试着打印下

    $tipi[0]='php-internal';

    $tipi[1]='php-internal';

    $tipi[2]='php-internal';

      

    var_dump(memory_get_usage());

      

    $copy = $tipi;

      

    xdebug_debug_zval('tipi', 'copy');

      

    var_dump(memory_get_usage());

      

    $copy[0] = '123';

      

    xdebug_debug_zval('tipi', 'copy');

      

    var_dump(memory_get_usage());

    结果如下:(注意:该结果是php5.6web环境下的,php7的引用不同)



    可看出,当$arr把值赋值给$arr_copy时,执行内存是没有明显变化的,并没有直接增加5443320内存量

    甚至在之后的foreach遍历中,也是没有增加内存的.

    因为当$arr赋值给$arr_copy时,并不是在内存中复制了整个$arr的值,而是将$arr_copy的值指向了$arr,相当于在取$arr_copy的数据时,指向的还是$arr存值的内存

    也就是说,就算我们不使用引用,php变量在传值,赋值的情况,都是指向同一个内存,但是如果当$arr_copy的值改变了会怎么样呢?

     

    <?php

    var_dump(memory_get_usage());

    //$tipi = array_fill(0, 3, 'php-internal');

    //不用array_fill的原因可自己试着打印下

    $tipi[0]='php-internal';

    $tipi[1]='php-internal';

    $tipi[2]='php-internal';

     

    var_dump(memory_get_usage());

     

    $copy = $tipi;

     

    xdebug_debug_zval('tipi', 'copy');

     

    var_dump(memory_get_usage());

     

    $copy[0] = '123';

     

    xdebug_debug_zval('tipi', 'copy');

     

    var_dump(memory_get_usage());

    结果如下:(注意:该结果是php5.6web环境下的,php7的引用不同)

    仙士可博客

    可以看出,当$copy[0]值改变时,php将会给$copy[0]重新申请内存,然后赋之以新值,但不影响其他值的内存状态。 写时复制的最小粒度,就是zval结构体, 而对于zval结构体组成的集合(如数组和对象等),在需要复制内存时,将复杂对象分解为最小粒度来处理。 这样做就使内存中复杂对象中某一部分做修改时,不必将该对象的所有元素全部“分离”出一份内存拷贝, 从而节省了内存的使用。

    (文中的xdebug_debug_zval是xdebug扩展中的函数,用于查看变量的引用信息)

    以上就是phpCOW机制详解的详细内容,更多请关注php中文网其它相关文章!

  • 相关阅读:
    夺命雷公狗---javascript NO:11 事件对象1
    夺命雷公狗---javascript NO:10 解决事件监听兼容性问题和移除事件
    夺命雷公狗---javascript NO:09 事件绑定的种类1
    夺命雷公狗---javascript NO:08 常用的事件
    夺命雷公狗---javascript NO:07 事件编程介绍
    夺命雷公狗---javascript NO:06 数组定义和遍历
    夺命雷公狗---javascript NO:05 js函数中的作用域
    夺命雷公狗---javascript NO:04 js中的函数
    夺命雷公狗---javascript NO:03 流程结构
    夺命雷公狗---javascript NO:02 数据类型和运算符
  • 原文地址:https://www.cnblogs.com/lxwphp/p/9955673.html
Copyright © 2011-2022 走看看