Let’s start with an example:
<?php $foo = 1; $bar = $foo; echo $foo + $bar;
The variable $foo is assigned to the variable $bar. These two variables have the same value. There is no need to apply for new memory space. They can share the same memory. PHP's COW optimizes memory in many scenarios. For example: multiple assignments of variables, passing function parameters, and modifying actual parameters in the function body, etc.
What is "copying"
This is an example taken from Brother Niao's blog. It makes it clearer, so I posted it directly.
<?php $var = "laruence"; $var_dup = $var; $var = 1; ?>
Obviously after this code is executed, the value of $var_dup should still be "laruence", so how is this achieved? This is PHP's copy on write mechanism:
Before modifying a variable, PHP will first check the refcount of the variable. If the refcount is greater than 1, PHP will execute a separate routine. For the above code, When executing the third line, PHP finds that the refcount of the zval pointed to by $var is greater than 1, then PHP will copy a new zval, reduce the refcount of the original zval by 1, and modify the symbol_table so that $var and $var_dup Separation. This mechanism is the so-called copy on write.
Copy on Write Application Scenarios
Copy on Write (also abbreviated as COW) has many application scenarios, such as copying the memory of a process in Linux The optimization used has similar applications in various programming languages, such as C, STL, etc. COW is a commonly used optimization method and can be classified into: delayed allocation of resources. Resources are only occupied when they are actually needed. Copy-on-write can usually reduce resource usage.
An example that proves that PHP COW optimizes memory usage:
<?php $j = 1; var_dump(memory_get_usage()); $tipi = array_fill(0, 100000, 'php-internal'); var_dump(memory_get_usage()); $tipi_copy = $tipi; var_dump(memory_get_usage()); foreach ($tipi_copy as $i) { $j += count($i); } var_dump(memory_get_usage());
Running results:
$ php t . php int(630904) int(10479840) int(10479944) int(10480040)
The memory is not significantly improved.
The principle of "copy-on-write"
Sharing the same memory with multiple variables of the same value does save memory space, but the value of the variable will change. , if in the above example, the value pointing to the same memory changes (or may change), the changed value needs to be "separated". This "separation" operation is "copying".
In PHP, in order to distinguish whether the same zval address is shared by multiple variables, the Zend engine introduces two variables, ref_count and is_ref, for identification:
ref_count and is_ref are defined in the zval structure The
is_ref mark in the body is a mandatory reference by the user using &;
ref_count is a reference count, used to identify how many variables this zval is referenced, that is, the automatic reference of COW, when it is 0 will be destroyed;
Note: It can be seen that there is no difference in PHP's use of memory between $a=$b; and $a=&$b; (when the value does not change);
I believe everyone can also understand the implementation principle of COW in PHP: COW in PHP is implemented based on reference counting ref_count and is_ref. If there is an additional variable pointer, ref_count will be increased by 1, otherwise subtracted by 1, and destroyed when it is reduced to 0; the same Reason, if there is one more mandatory reference &, is_ref will be increased by 1, otherwise it will be subtracted by 1.
The above is the detailed content of PHP copy on write (Copy On Write). For more information, please follow other related articles on the PHP Chinese website!