Mar 11 in-depth understanding of PHP memory management who moved my memory
- Author: laruence ()
- This address: http://www.laruence.com/2011/03/04/1894.html
- Reprint please indicate the source
First let's look at a problem: the output of the following code,
- Var_dump(memory_get_usage());
- $a = "Laruence";
- Var_dump(memory_get_usage());
- unset($a);
- Var_dump(memory_get_usage());
The output (on my PC, may vary depending on the system, PHP version, load extension):
- Int (90440)
- Int (90640)
- Int (90472)
Notice 90472-90440=32, so there are a variety of conclusions, some people say that PHP unset does not really release memory, some say, PHP unset only in the release of large variables (a large number of strings, large arrays) when the real free memory, more people say, There is no point in discussing memory at the PHP level.
So, in the end unset will not release memory? Where did these 32 bytes go?
To answer this question, I'll start with two things:
Where did these 32 bytes go?
First we have to break a thinking: PHP is not like C, only you display the call memory allocation related APIs will have memory allocation.
In other words, there are a lot of memory allocation procedures that we don't see in PHP.
For example:
- $a = "Laruence";
The implicit memory allocation points are:
- 1. Allocating memory to the variable name and storing it in the symbol table
- 2. Allocating memory for variable values
So, you can't just look at appearances.
Second, don't doubt that PHP's unset does release memory (and, of course, the combination of references and counts, this part of the article, see my previous articles in-depth understanding of the PHP principle of variable separation/reference), but this release is not a C programming sense of release, not to be handed back to the OS.
For PHP, it provides itself with a set of memory management APIs similar to the C language for memory allocation:
- Emalloc(size_t size);
- Efree(void *ptr);
- Ecalloc(size_t nmemb, size_t size);
- Erealloc(void *ptr, size_t size);
- Estrdup(const char *s);
- Estrndup(const char *s, unsigned int length);
These APIs correspond to the API meanings of C, which are managed by these APIs within PHP.
When we call Emalloc to request memory, PHP is not simply to the OS to memory, but will be like the OS to a chunk of memory, and then assign one piece to the applicant, so when there is logic to request memory, it is no longer necessary to the OS to request memory, avoid frequent system calls.
For example, the following examples:
- <?php
- Var_dump(memory_get_usage(TRUE)); //Pay attention to getting the real_size
- $a = "Laruence";
- Var_dump(memory_get_usage(TRUE));
- unset($a);
- Var_dump(memory_get_usage(TRUE));
Output:
- Int (262144)
- Int (262144)
- Int (262144)
That is, when we define the variable $ A, PHP does not request new memory from the system.
Similarly, when we call Efree to release memory, PHP does not return the memory to the OS, but it will put this memory into the list of free memory that it maintains. For small chunks of memory, it is more likely to put it in the memory cache list (PostScript, some versions of PHP, such as my verified PHP5.2.4, 5.2.6, 5.2.8, in the call Get_memory_usage (), does not subtract the size of the available memory blocks in the memory cache list, resulting in the appearance that the memory will not change after unset, see comments).
Now let me answer these 32 bytes where to go, as I just said, a lot of memory allocation process is not explicit, read the following code you understand:
- <?php
- Var_dump("I am laruence, from http://www.laruence.com");
- Var_dump(memory_get_usage());
- $a = "Laruence";
- Var_dump(memory_get_usage());
- unset($a);
- Var_dump(memory_get_usage());
Output:
- String ("I am laruence, from http://www.laruence.com")
- Int (90808)//before assignment
- Int (90976)
- Int (90808)//Yes, the memory is normally released.
90808-90808 = 0, normal, that is to say, these 32 bytes are consumed by the output function (strictly speaking, is the output of the header occupied)
An array that only increases in weight
Hashtable is the core structure of PHP (understand Hashtable, you can see my previous article in-depth understanding of the PHP array (traversal order)), the array is also used by her to express, and the symbol table is an associative array, for the following code:
- Var_dump("I am laruence, from http://www.laruence.com");
- Var_dump(memory_get_usage());
- $array = Array_fill(1, +, "laruence");
- foreach ($array as $key = = $value) {
- ${$value . $key} = NULL;
- }
- Var_dump(memory_get_usage());
- foreach ($array as $key= = $value) {
- unset(${$value . $key});
- }
- Var_dump(memory_get_usage());
We define 100 variables and then press a unset them to see the output:
- String ("I am laruence, from http://www.laruence.com")
- Int (93560)
- Int (118848)
- Int (104448)
Wow, why is it so much less memory?
This is because for Hashtable, when defining it, it is not possible to allocate enough memory block at a time to save the unknown number of elements, so PHP will be initialized at the time, just allocate a small portion of memory to Hashtable, when not enough time to resize expansion,
And Hashtable, can only expand, will not be reduced, for the above example, when we deposit 100 variables, the symbol table is not enough to do a single expansion, and when we unset out these 100 variables in turn, the variable occupied memory is released (118848–104448), but The symbol table does not shrink, so these little memory is taken up by the symbol table itself ...
Now, do you have a preliminary understanding of the memory management of PHP?
PHP Memory processing Instructions "Go"