PHP extensions and Embedding--php memory management _php Tutorials

Source: Internet
Author: User
PHP's memory management mechanism is quite exhaustive, and it is more similar to Java's garbage collection mechanism at this point. For C or C + + most of the time, the programmer can only release the application space. In PHP, because of the thousands of connections that are needed, these connections often take a long time to maintain. This is not the same as when the program ends in C and the corresponding memory blocks are recycled.

So it is not enough to rely on programmers to pay attention to memory recycling when writing programs, and PHP must have its own internal, connection-related memory management mechanisms to ensure that no memory leaks occur.

In this article, we first introduce the memory mechanism of PHP:

Those spatial functions in the C language, such as malloc () free () StrDup () realloc () calloc (), have different forms in PHP.


To return the requested memory : For programmers, each piece of the requested memory should be returned, if not also cause a memory leak. In programs that don't require running all the time, a little memory leak ends when the entire process is killed. But like Apache, a Web server that runs all the time, a small memory leak can eventually cause a program to crash.


Examples of error handling :

In the case of error handling, the mechanism is generally Zend engine will set a jump-off address, once the exit or die or any serious error e_error, will use a longjmp () jump to this address. But this approach almost always leads to memory leaks. Because the free operation will be skipped. (This problem also exists in C + +, that is, in the design class, the error handling or alarm function must not be written in the construction or destructor, the same reason, because the object is already in the stage of destruction or creation, so any error function processing can interrupt this process, which may lead to memory leaks.) This example is given in the following code:
void call_function (const char *fname, int fname_len tsrmls_dc) {zend_function *fe;    Char *lcase_fname; /* PHP function names is case-insensitive to simplify locating them in the function tables all function names is Implici tly * translated to lowercase */lcase_fname = Estrndup (fname, Fname_len);//Create a copy of the function name Zend_str_tolower (lcas    E_fname, Fname_len);//convert to lowercase, which is handy when looking for, which should also be the way to function identification in PHP function tables. if (Zend_hash_find (EG (function_table), Lcase_fname, Fname_len + 1, (void *) &fe) = = FAILURE) {? SUCCESS.        This is to find the function to be called in the function table.    Zend_execute (Fe->op_array tsrmls_cc); } else {php_error_docref (NULL tsrmls_cc, E_error, "call to undefined function:%s ()" , fname); Equivalent to Trigger_error ()} efree (Lcase_fname);} 
In this example, a PHP function is provided when invoking a function. When PHP calls the function, it needs to go to the function table that is function_table to find the corresponding function, and before looking for the first to convert to lowercase letters, so that in the search can improve the efficiency of the search. The Zend_hash_find function is invoked using Zend_execute if it finds the function to be called. And if not find haunted will jump out of error, show not found. But here's the problem, notice that the function name string was created in the lowercase version of the function in order to look for functions. This string has been to use the Zend_hash_find function, once not found into the error, then the corresponding memory space of the string must not be found, which caused the memory leak.

As a result, PHP provides Zend Memory Management, Zend memory management is also known as ZENDMM.
  • Memory Management in PHP is similar to the operating system's mechanism, but the object is for the memory involved in each request.
  • In addition ZENDMM will also control the INI file within the MeMZ yo? http://www. bkjia.com/kf/ware/vc/"target=" _blank "class=" Keylink ">vcnlfbgltaxsjrnkyvs3kx8u10ru1qco/upbh68fzy/ nsqsfztcte2rtms6y5/chl1ek49m1lbw9yesbsaw1pdkosxmfdtnkyu+hj6sfryqew3kgjpgxppttazbzw0lxe1+7pwspmv7s1vchly/ zt67lz1/fptc2zz+dbqs+1tctsu7ljoapv67bustnx98+1zbpw0lxeserxvlxexnq05snqx+ U6zcrnt8w1xle9t6ijrhbocnbqtrzt0lbu06a1xlqvyv2ho9xi0km6r8r9sqkyu8rh0ru49rzytaw1xmzmu7ujrmv8w8fw0ld8uqzt0mzytqi1xndfz6kjrnt a1elqqddfz6k1xldv1vrpwr7nxny5u7drw7+49sfrx/pl+cnqx+u1xmtatoa/6b340ncx6sq2oapv4th5vs3e3lm7yrxp1rbuw7+49sfrx/ o1xmtatobh+npyvfjq0lfwsfc1xlncwo2hozxsat7nrmqx1nrnvnbqv7s1vchl0ru5ssg91tbe2rtmx+ vh87xet73kvao6cgvyc2lzdgvudlrncgvylxjlcxvlc3sjrlbu09pwzxjzaxn0zw50wltltblusru24lj6z7xns7xex+vh877n0rvr+ chlo6zssr7nysfltcrhtsdbottaw7/su7j2x+vh89auzek1xkossru74dtax+ vh873hyvjwrrrzsbu72mrvoao1q8rh09dksbryyse38xblcnnpc3rlbns/yctc0qpydw50aw1lssxe3naqtccjrmv50ttu2txi1tbh6b/ 2z8kjrndo0qrsu7j2zmxhz8c01rjkvtxi0ru146gjtttt2srht/hkx3blcnnpc3rlbnsjrl340nde2rtmx+vh87xet73kvcrhsrvsu9h5tcsho8/cw+a4+lp2ttttprnyz7wjugokphvspgo8bgk+cgvtywxsb2moynvmzmvyx2xlbiwxksa9psbtywxsb2moynvmzmvyx2xlbik8bgk+ cgvybwfsbg9jkgj1zmzlcl9szw4smckgpt0gzw1hbgxvyyhidwzmzxjfbgvukdxi1tbbqs+ 1ysftw7rqtqjs5bxet73kvb72tqi1xdxsat4jzgvmaw5lihblbwfsbg9jkhnpemuscgvyc2lzdgvudckgxdxsat4kcgo8bgk+ Cjx1bd4kkchwzxjzaxn0zw50kt9tywxsb2moc2l6zsk6zw1hbgxvyyhzaxplkskkcmzsywc9mbhtyr7kx3blcnnpc3rlbns1xkoszqowse3kvrk7ysejrl7nu prsu7djtcs4vcr009rh68fztcrlbwfsbg9j0rvr+chloamkpgjypgokcjxicj4kcs/czbzw0l/j0ts/tlw9z7xns7xexnq05snqx+u6r8r90+ twahdw0lxexnq05snqx+u6r8r9tcs21lhi16q7u828o7okcjxpbwcgc3jjpq== "http://www. Bkjia.com/uploadfile/collfiles/20131213/20131213091641239.jpg "alt=" \ ">
    If you are not familiar with the functions of malloc, Calloc, and realloc, please go to: http://www.cppblog.com/sandywin/archive/2011/09/14/155746.html
    In addition, there are twomemory functions in Safe Mode: void *safe_emalloc (size_t size, size_t count, size_t ADDTL);
    void *safe_pemalloc (size_t size, size_t count, size_t Addtl, char persistent); The space they applied for was Size*count + ADDTL, The reason for this is to avoid the overflow of type int.


    And then say a more interesting, reference Count in PHP:
    Many languages have references, and many times they use references. Using references saves space, because sometimes it is not necessary to make a copy of each variable. The so-called reference count refers to how many variables are referenced in the same memory space, thus avoiding possible memory error operations. Let's look at the following section of code:
    * {*     zval *helloval;*     make_std_zval (helloval); *     zval_string (helloval, "Hello World", 1); *     Zend_hash _add (eg (active_symbol_table), "a", sizeof ("a"), *                                            &helloval, sizeof (zval*), NULL); *     zend_hash_add (eg ( active_symbol_table), "B", sizeof ("B"), *                                            &helloval, sizeof (zval*), NULL);
    This code first declares a Zval variable, and then initializes it with Make_std_zval, followed by a zval_string with the initial value. Then, for this variable, two variable names are given. The first one is a, the second is B, and there is no doubt that the second one is definitely a reference. But there must be a problem with this code, and the problem is that you didn't update the reference count after you used Zend_hash_add. Zend does not know that you have added such a reference, which can cause two releases when the memory is freed. So the correct code after the modification is as follows:
    * {*     zval *helloval;*     make_std_zval (helloval); *     zval_string (helloval, "Hello World", 1); *     Zend_hash _add (EG (active_symbol_table), "a", sizeof ("a"), *                                            &helloval, sizeof (zval*), NULL); *     Zval_addref ( Helloval); With this, there will be no more errors to re-release the same memory space *     Zend_hash_add (EG (active_symbol_table), "B", sizeof ("B"), *                                            &helloval, sizeof (zval*), NULL); *}
    After Zval_addref, the next time the unset variable is checked, the Ref_count reference count is viewed first, and if the =1 is released, if the >1 is just-1, no memory is released.
    Copy on WriteLet's look at the following PHP code:
     
        
    Obviously in the second line when B declares a reference to a, then after the execution of the third line of code, b increased, a increase does not increase it? Many times may not want to increase. So this time, when Zend detects refcount>1, it performs a variable separation operation, turning the original piece of memory into two pieces of memory:
    Zval *get_var_and_separate (char *varname, int varname_len tsrmls_dc) {zval **varval, *varcopy; if (Zend_hash_find (EG (active_symbol_table), varname, Varname_len + 1, (void**) &varval) = = Failur   E) The {/* sign table does not find */return NULL;   } if ((*varval)->refcount < 2) {/* varname is the only reference, nothing to do */return *varval;       }/* Otherwise, not the only reference, make a copy to zval* */Make_std_zval (varcopy);   Varcopy = *varval; /* Duplicate Any allocated structures within the zval* */Zval_copy_ctor (varcopy); How is this piece copied?  Mark should have been connected to the varval corresponding to the varname/* To delete the varname version, which will reduce the number of citations of varval */Zend_hash_del (EG (active_symbol_table), varname,   Varname_len + 1);       /* Initialize the number of references to the newly created value, and then attach to the varname variable */varcopy->refcount = 1;       Varcopy->is_ref = 0; Zend_hash_add (EG (active_symbol_table), varname, Varname_len + 1, &varcopy, size   Of (zval*), NULL); /* Return the new zval* */return varcopy;}
    First saw two judgment statements, the first judgment statement in the symbol table to see if there is a corresponding variable, if not found there is no need to separate. The second judgment statement is to see if the number of references entered is less than 2, and if so, then the input variable *varval is unique and does not need to be separated. Otherwise, there must be a reference, this time to make a copy varcopy. This copy inherits the value of the varname, but the difference is that it re-applies the memory space and re-initializes the RefCount and Is_ref parameters. Take A, B for example, after $b+=5, after execution, b as varname to find whether there is a reference, found that there is a reference to a, this time the value of B is copied out, and then re-apply a space, re-registered as B. That would be two blocks of independent memory.

    Change on WriteLet's look at a code snippet:
     
        
    If you think you want A to change with B, that's fine, as long as you explicitly use the & symbol to make a reference declaration. In this case, the IS_REF flag will be placed 1. There is no need to detach the memory block at this time. So, in the above code, you want to change the judgment of the second if statement:
    if ((*varval)->is_ref | | (*varval)->refcount < 2) {/    * varname are the only actual reference,     * or it's a full reference to other Vari Ables     * Either way:no separating to being done     */    return *varval;}


    In the final case, this is the most tangled scenario:
     
        
    Neither copy on write nor change on Wirte, there is no way, had to separate. Here, B is independent:







    Some of the mechanisms of PHP memory management here, I feel PHP is really a very magical language. Ha ha.

    http://www.bkjia.com/PHPjc/621625.html www.bkjia.com true http://www.bkjia.com/PHPjc/621625.html techarticle PHP's memory management mechanism is quite exhaustive, and it's more of a Java-like garbage collection mechanism at this point. And for C language or C most of the time can only be applied by the programmer himself to the space ...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.