What is Copy On Write )?
A: copying an object does not really copy the original object to another location in the memory, but sets a pointer in the memory ing table of the new object, refers to the location of the source object, and sets the Copy-On-Write bit of the memory to 1. in this way, when the read operation is performed on the new object, the memory data does not change, and the read operation is executed directly. When the write operation is performed on the new object, copy the real object to the new memory address, modify the memory ing table of the new object to point to the new location, and perform write operations on the new memory location.
This technology needs to be used together with the virtual memory and paging. The advantage is that when performing the copy operation, because it is not a real memory copy, it just creates a pointer and thus greatly improves the efficiency. However, this is not always true. If you copy a new object, most objects still need to be written, resulting in a large number of paging errors, which is not worth the candle. So COW is efficient only when the new object is copied, the write operation is performed on a small part of the memory paging.
In the PHP kernel, the replication mechanism for writing is also used to avoid Memory increase when values are assigned. For example, when we use the foreach loop body, we can discover the mysteries. Example code:
Copy codeThe Code is as follows:
$ M1 = memory_get_usage ();
$ Str = <EOF
Aaaaaaaaaaaaaa
Aaaaaaaaaaaaaa
Aaaaaaaaaaaaaa
EOF;
$ Arr = explode ("\ n", $ str );
$ Count = 0;
Foreach ($ arr as $ v ){
$ Count ++;
// $ V = 'aaaaaaaaaaaaaaa ';
}
$ M2 = memory_get_usage ();
Echo $ m2-$ m1;
When we execute this code, the memory usage will be: 788.
Copy codeThe Code is as follows:
$ M1 = memory_get_usage ();
$ Str = <EOF
Aaaaaaaaaaaaaa
Aaaaaaaaaaaaaa
Aaaaaaaaaaaaaa
EOF;
$ Arr = explode ("\ n", $ str );
$ Count = 0;
Foreach ($ arr as $ v ){
$ Count ++;
$ V = 'aaaaaaaaaaaaaaa ';
}
$ M2 = memory_get_usage ();
Echo $ m2-$ m1;
When we cancel the annotation of // $ v = 'aaaaaaaaaaaaaaa';, the memory usage value is 840. Note that the memory usage increases.
Copy codeThe Code is as follows:
$ M1 = memory_get_usage ();
$ Str = <EOF
Aaaaaaaaaaaaaa
Aaaaaaaaaaaaaa
Aaaaaaaaaaaaaa
EOF;
$ Arr = explode ("\ n", $ str );
$ Count = 0;
Foreach ($ arr as & $ v ){
$ Count ++;
// $ V = 'aaaaaaaaaaaaaaa ';
}
$ M2 = memory_get_usage ();
Echo $ m2-$ m1;
When we change $ v in foreach to & $ v, regardless of whether or not to comment $ v in the loop body, we can get the memory usage: 788.
Here we illustrate the COW mechanism intervention. When we use only the read operations on $ v in the foreach loop, the PHP kernel points the memory address of the $ v variable to the memory address of the index of $ arr, and does not copy the data in the array to the variable $ v, in this case, the memory usage is the same as the usage & $ v. But when we write $ v in the loop body, the replication mechanism is activated when writing, and PHP will re-open a memory space to the $ v variable, however, if you disconnect the memory address from the original $ v pointing to the array, the memory will inevitably increase.
Here we can draw another conclusion: when reading big data, we should pay attention to the impact of memory growth introduced by the COW mechanism and avoid unnecessary variable writing, it can improve the code running performance.