Introduction of copy on write Write time Replication Mechanism in PHP

  • 2021-06-28 11:30:53
  • OfStack

What is write-time replication (Copy On Write)?

Answer: When you copy an object, you don't really copy the original object to another location in memory. Instead, you set a pointer in the memory map of the new object, point to the location of the source object, and set the Copy-On-Write bit of that memory to 1. That way, when you read a new object, there will be no change in the memory data.Perform read operations directly;When you write to a new object, copy the real object to the new memory address, modify the memory map of the new object to point to the new location, and write to the new memory location.

This technique needs to be used in conjunction with virtual memory and paging. The benefit is that when performing a replication operation, it is much more efficient because it is not a real memory replication, but only a pointer is set up.However, this is not always true. If you copy a new object, most objects still need to continue to write, which will result in a large number of paging errors at no cost.Therefore, COW is efficient only for writing on a small part of the memory paging after copying new objects.

Write-time replication is also used in the PHP kernel to avoid memory gain during assignment. For example, when we use the foreach loop body, we can discover the secret. Sample code:


$m1 = memory_get_usage();
$str=<<<EOF
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
EOF;
$arr = explode("\n", $str);
$count=0;
foreach($arr as $v){
    $count++;
    //$v='aaaaaaaaaaaaaa';
}
$m2 = memory_get_usage();
echo $m2-$m1;

When we execute this code we get a memory footprint of 788


$m1 = memory_get_usage();
$str=<<<EOF
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
EOF;
$arr = explode("\n", $str);
$count=0;
foreach($arr as $v){
$count++;
$v='aaaaaaaaaaaaaa';
}
$m2 = memory_get_usage();
echo $m2-$m1;

When we cancel //$v='aaaaaaaaaaaaaa';Note, at this point the memory usage value is: 840, notice the memory growth.


$m1 = memory_get_usage();
$str=<<<EOF
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
EOF;
$arr = explode("\n", $str);
$count=0;
foreach($arr as &$v){
$count++;
//$v='aaaaaaaaaaaaaa';
}
$m2 = memory_get_usage();
echo $m2-$m1;

When we rewrite $v from foreach to & At $v, we get a memory footprint of 788 whether or not we comment on $v in the loop body

This illustrates the involvement of the COW mechanism. When we only use a pure read of $v in the foreach loop, the PHP kernel will point the memory address of the variable $v to the memory address of the index of the array in $arr. It does not copy a copy of the data in the array to the variable $v, at which point the memory usage and usage are & $v is the same.However, when we write $v in the loop, the copy mechanism is activated at the time of writing, and PHP reclaims a section of memory space to the $v variable, disconnecting the memory address that originally pointed to the array, and memory must grow.

Here's another conclusion: when reading large data, we should be aware of the impact of memory growth introduced by the COW mechanism, and avoid unnecessary variable writing, which can improve code performance.


Related articles: