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中文网其它相关文章!

  • 相关阅读:
    Ubuntu 16 安装redis客户端
    crontab 参数详解
    PHP模拟登录发送闪存
    Nginx配置端口访问的网站
    Linux 增加对外开放的端口
    Linux 实用指令之查看端口开启情况
    无敌的极路由
    不同的域名可以指向同一个项目
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error
    Redis 创建多个端口
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15453764.html
Copyright © 2011-2022 走看看