PHP Memory Management Detailed

Source: Internet
Author: User

Memory Management in PHP

The most important difference between PHP and C is the control of memory pointers.

Memory

In PHP, it's simple to set a string variable: <?php $str = ' Hello World ';, strings can be modified, copied, and moved freely. In C, it's another way, although you can simply initialize it with a static string: char *str = "Hello World"; However, this string cannot be modified because it exists in the code snippet. To create a maintainable string, you need to allocate a piece of memory and use a function such as strdup () to copy the content to it.

{  
   char *str;  
      
   str = strdup ("Hello World");  
   if (!str) {  
       fprintf (stderr, "Unable to allocate memory!");  
   }  

The traditional memory management functions (malloc (), free (), StrDup (), realloc (), calloc (), etc.) are not used directly by PHP's source code, and this chapter explains why.

Freeing allocated memory

Memory management is handled in a request/release manner on all previous platforms. The application tells it that the upper layer (usually the operating system) "I want some memory usage", if space allows, the operating system is provided to the program and a record of the memory provided out.

After the application has finished using memory, the memory should be returned to the OS so that it can be assigned to other places. If the program does not return memory, the OS has no way of knowing that the memory is no longer in use, so that it cannot be allocated to other processes. If a piece of memory is not released and the application that owns it loses its handle, we are called "leaks" because no one can get it directly.

In a typical client application, small infrequent leaks are usually tolerable because the process terminates after a period of time, so that the leaked memory is reclaimed by the OS. It's not that the OS is very cow aware of the leaking memory, but it knows that the memory allocated for the terminated process is no longer available.

For long-running service-side daemons, including webserver such as Apache, processes are designed to run for a long period of time, usually indefinitely. As a result, the OS cannot interfere with memory usage, and any amount of leakage, however small, can accumulate enough to cause system resources to run out.

Consider the STRISTR () function of user space; To do case-insensitive lookup strings, it actually creates a lowercase copy of the haystack and needle, and then performs a common case-sensitive search to find the relevant offset. After the offset of the string is positioned, the lowercase versions of the haystack and needle strings are no longer used. If these copies are not released, each script that uses STRISTR () will leak some memory each time it is invoked. Eventually, the webserver process consumes the entire system's memory, but it is not used.

The perfect solution is to write good, clean, consistent code to ensure that they are absolutely correct. In an environment like the PHP interpreter, however, this is only half the solution.

Error handling

To provide the ability to jump out of the activation requests of user scripts and the extension functions in which they reside, there is a need for a way out of the entire activation request. The processing in the Zend engine is to set a pop-up address at the start of the request, after all Die ()/exit () is invoked, or when a critical error (E_ERROR) is encountered, the longjmp () is directed to the preset pop-up address.

While this leap-through process simplifies the process, there is a problem: resource cleanup code (such as free () calls) is skipped, which can lead to leaks. Consider the following simplified engine handler code for the function call:

void call_function (const char *fname, int fname_len tsrmls_dc)  
{  
    zend_function *fe;  
    char *lcase_fname;  
    * PHP functions are case insensitive, in order to simplify their positioning in the function table, all the function names are implicitly translated to lowercase * * * *
    lcase_fname = estrndup (fname, Fname_len);  
    Zend_str_tolower (Lcase_fname, Fname_len);  
      
    if (Zend_hash_find (EG function_table),  
            lcase_fname, Fname_len + 1, (void * *) &fe) = = failure) {  
        Zend_execute (Fe->op_array tsrmls_cc);  
    } else {  
        php_error_docref (NULL tsrmls_cc, E_error,  
                         "Call to undefined function:%s ()", fname);  
    }  
    Efree (Lcase_fname);  
}

When the Php_error_docref () line executes, the internal processor sees the error level as critical, calls LONGJMP () interrupts the current program flow, and leaves Call_function () so that it cannot reach the Efree (lcase_fname) row. You might want to move the Efree () line to Php_error_docref (), but what if the call_function () call goes into the first conditional branch (the name of the function is found, normally executed)? Also, fname is an assigned string, and it is used in error messages and you cannot release it until it is used.

The Php_error_docref () function is an internal equivalent to Trigger_error (). The first parameter is an optional document reference that is appended to the Docref.root if enabled in PHP.ini. The third argument can be any e_* family constant that marks the severity of the error. The fourth and subsequent parameters are a list of format strings and variable parameters that conform to the printf () style.

Zend Memory Management

The solution to the memory leak caused by a request to jump out of (a failure) is the Zend Memory management (ZENDMM) layer. This part of the engine plays the role that the operating system normally plays, allocating memory to the calling application. The difference is that, standing in the cognitive perspective of the process space request, it is die enough to perform the same things that the OS did when the process die when the request was made. That is, it implicitly releases all the memory space that the request has. The following illustration shows the relationship between ZENDMM and OS in the PHP process:

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.