参考Be wary of garbage collection 先看段代码:

echo "Stage 1: Mem usage is: ", memory_get_usage(), "\n";

  $arr = array();

  for ($i = 0; $i < 1000000; ++$i) {
    $arr[] = rand();
  }

  echo "Stage 2: Mem usage is: ", memory_get_usage(), "\n";

  $foo = 1;
  $bar = 2;

  echo "Stage 3: Mem usage is: ", memory_get_usage(), "\n";

  $foo = $arr;
  $bar = $arr;

  echo "Stage 4: Mem usage is: ", memory_get_usage(), "\n";

$arr = array();

  echo "Stage 5: Mem usage is: ", memory_get_usage(), "\n";

  $bar[] = "hello, world";

  echo "Stage 6: Mem usage is: ", memory_get_usage(), "\n";

  $foo = array();

  echo "Stage 7: Mem usage is: ", memory_get_usage(), "\n";

运行结果:

Stage 1: Mem usage is: 37712
Stage 2: Mem usage is: 60232136
Stage 3: Mem usage is: 60232248
Stage 4: Mem usage is: 60232248
Stage 5: Mem usage is: 60232288
Stage 6: Mem usage is: 104426704
Stage 7: Mem usage is: 60242672

看stage 4,

  $foo = $arr;
  $bar = $arr;

  echo "Stage 4: Mem usage is: ", memory_get_usage(), "\n";

arr被拷贝到了foo,bar,现在那个数组有了三份引用,然而内存却没有变化!这就是copy on write, 现在arr,foo,bar都指向了同一个内部数组。 Stage 5,$arr = array(), 内存却几乎没有变化 Stage 6,$bar[] = “hello, world”, $bar中插入一条新数据,内存急剧增大,为什么呢?因为这时候开始修改$bar变量了,copy on write机制运行了,这是foo,bar指向了不同的数组。 Stage 7,$foo = array(),foo这个变量重置,内存也急剧下降。