Php expansion and embedding-php memory management

Source: Internet
Author: User
Php's memory management mechanism is quite detailed. it is more like & amp; 20284; and java's garbage collection mechanism. For c language or c & amp; 43; & amp; 43; most of the time, programmers can only release the applied space. In php, because we need to deal with thousands of connections

Php's memory management mechanism is quite detailed, which is more similar to java's garbage collection mechanism. For c language or c ++, programmers can only release the applied space. In php, to deal with thousands of connections, these connections often need to be maintained for a long time. This is not the same as that in c, when the program finishes the corresponding memory block, it will be recycled.

Therefore, it is not enough to rely solely on programmers to pay attention to memory reclaim when writing programs, php must have some internal connection-related memory management mechanisms to prevent any memory leakage.

In this articleMemory mechanismHere is an introduction:

Spatial functions in C language, such as malloc () free () strdup () realloc () calloc (), have different forms in php.


Return applied memory: For programmers, the memory applied for each block should be returned. if it is not returned, it will cause memory leakage. In programs that do not require continuous running, a slight memory leak ends after the entire process is killed. However, for a web server that has been running like apache, a small memory leak will eventually cause the program to crash.


Example of error handling:

During error handling, the mechanism used is generally that Zend Engine sets an exit address. Once exit or die or any serious error E_ERROR occurs, A longjmp () is used to jump to the address. However, this will almost cause memory leakage. Because free operations are skipped. (This problem also exists in c ++, that is, when designing a class, never write error handling or alarm functions in the constructor or destructor for the same reason, because the object is already in the destruction or creation stage, any error function processing may interrupt this process, which may cause memory leakage .) The following code provides an example:
Void call_function (const char * fname, int fname_len TSRMLS_DC) {zend_function * fe; char * lcase_fname; /* PHP function names are case-insensitive to simplify locating them in the function tables all function names are implicitly * translated to lowercase */lcase_fname = estrndup (fname, fname_len ); // create a copy of the function name zend_str_tolower (lcase_fname, fname_len); // Convert all to lowercase, which is convenient to search, this should also be used to identify functions in the php function table. 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 calling a function. When php calls a function, it needs to find the corresponding function in the function table, that is, function_table. before searching, it needs to be converted to lowercase letters, this improves the search efficiency. If the zend_hash_find function finds the function to be called, use zend_execute to call it. If the haunted cannot be found, an error is reported, indicating that the haunted cannot be found. However, the problem arises. Note that a function name string of lower-case version has been created to search for a function. This string is used until the zend_hash_find function is used. once an error is returned, the memory space corresponding to this string cannot be found, which leads to memory leakage.

Therefore, php provides Zend memory managementZend memory management is also called ZendMM.
  • The memory management in php is similar to the operating system mechanism, but the object is for the memory involved in each request.
  • In addition, ZendMM also controls the memZ defined in the INI file ??" http://www.2cto.com/kf/ware/vc/ "Target =" _ blank "class =" keylink "> keys/uPbH68fzy/keys + 7PwsPmv7S1vcHLy/zT67LZ1/fPtc2zz + DBqs + keys + 49 sfrx/ PL + cnqx + u1xMTatOa/release + 49 sfrx/O1xMTatObH + release + vH877N0rvR + Release/Su7j2x + release + Release/Cw + a4 + Release + signature + export amkpgjypgokcjxicj4kcs/CzbzW0L/J0tS/signature + u6r8r90 + twaHDW0LXExNq05snqx + signature =" http://www.2cto.com/uploadfile/Collfiles/20131213/20131213091641239.jpg "Alt =" \ ">
    If you are not familiar with functions like malloc, calloc, and realloc, move on to the 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 Applied Space is size * count + addtl, which is used to avoid int overflow.


    Next, let's talk about something more interesting,In phpReference count:
    References are available in many languages and are often used. Space can be saved by referencing, because sometimes there is no need to create a copy for each variable. The reference count refers to the number of variables that reference the same memory space to avoid memory error operations. Let's take a look at the following 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, initializes it with MAKE_STD_ZVAL, and then attaches the initial value with ZVAL_STRING. Then, two variable names are given for this variable. The first is a and the second is B. There is no doubt that the second is a reference. However, there must be a problem with writing this code. The problem is that you have not updated the reference count after using zend_hash_add. Zend does not know that you have added such a reference, which may lead to two releases when the memory is released. The correct code after modification is as follows:
    * {* Zval * helloval; * MAKE_STD_ZVAL (helloval); * ZVAL_STRING (helloval, "Hello World", 1); * zend_hash_add (EG (active_symbol_table), "", sizeof ("a"), * & helloval, sizeof (zval *), NULL );*ZVAL_ADDREF (helloval );// After adding this, there will be no errors like re-releasing the same memory space * zend_hash_add (EG (active_symbol_table), "B", sizeof ("B "), * & helloval, sizeof (zval *), NULL );*}
    After ZVAL_ADDREF is performed, the next unset variable will first check the ref_count reference count. if it is equal to 1, it will be released. if it is greater than 1, it will be-1, and no memory will be released.
    Copy on WriteLet's take a look at the following php code:
       
    Apparently, in the second line, B declares a reference to a. after the code of the third line is executed, B is added and a is not added? In many cases, you may not want to increase the value. Therefore, after Zend detects refCount> 1, it will execute a variable separation operation to convert the original memory into two memories:
    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) = FAILURE) {/* the symbol table does not find */return NULL;} if (* varval)-> refcount <2) {/* varname is a unique reference and does not need to be used for anything */return * varval;}/*. Otherwise, it is not a unique reference, make a copy of zval */MAKE_STD_ZVAL (varcopy); varcopy = * varval;/* Duplicate any allocated Structures within the zval **/zval_copy_ctor (varcopy); // How is this copy? Mark should have connected the varname corresponding to varval/* delete the varname version, which will reduce the number of varval references */zend_hash_del (EG (active_symbol_table), varname, varname_len + 1 ); /* initialize the reference times of the new value and attach it to the varname variable */varcopy-> refcount = 1; varcopy-> is_ref = 0; zend_hash_add (EG (active_symbol_table ), varname, varname_len + 1, & varcopy, sizeof (zval *), NULL);/* Return the new zval **/return varcopy ;}
    First, we saw two judgment statements. the first judgment statement first checked in the symbol table to see if the corresponding variables were found. if not found, there is no need to separate them. The second statement is to check whether the number of input variable references is less than 2. if yes, the input variable * varval is unique and there is no need to separate it. Otherwise there must be references. a copy of varcopy is required at this time. This copy will inherit the value corresponding to varname, but the difference is that it re-applies for memory space and reinitializes the refcount and is_ref parameters. Take a and B as an example. after $ B + = 5 is executed, B acts as varname to check whether there is a reference. it is found that, at this time, copy the value of B, apply for a new space, and re-register as B. In this case, two independent memory blocks are created.

    Change on WriteLet's look at another code snippet:
       
    If you think that you want a to change along with B, there is no problem. you just need to explicitly use the & symbol for reference declaration. In this case, the is_ref flag is set to 1. at this time, there is no need to separate the memory blocks. In the above code, we need to change the judgment of the second if statement:
    if ((*varval)->is_ref || (*varval)->refcount < 2) {    /* varname is the only actual reference,     * or it's a full reference to other variables     * either way: no separating to be done     */    return *varval;}


    Looking at the last situation, this situation is the most tangled:
       
    Neither copy on write nor change on wirte, so there is no way to separate it. Here, B is independent:







    Speaking of some mechanisms for php memory management, I feel that php is indeed a magic language. Haha.

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.