Home Backend Development PHP Tutorial PHP extension and embedding--php memory management_PHP tutorial

PHP extension and embedding--php memory management_PHP tutorial

Jul 13, 2016 pm 05:18 PM
php Expand of

PHP’s memory management mechanism is quite detailed, and it is more similar to Java’s garbage collection mechanism in this regard. For C language or C++, most of the time, the programmer can only release the applied space. In PHP, due to the need to deal with thousands of connections, these connections often need to be maintained for a long time. This is different from the fact that the corresponding memory block will be recycled when the program ends in C.

So it is not enough to just rely on programmers to pay attention to memory recycling when writing programs. PHP must have some internal memory management mechanisms related to connections to ensure that no memory leaks occur.

In this article, we first introduce PHP’s memory mechanism:

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


Return the applied memory: For programmers, every piece of applied memory should be returned. Failure to do so will lead to memory leaks. In programs that are not required to run all the time, a small memory leak ends when the entire process is killed. But a web that is always running like apache server, small memory leaks will eventually cause the program to crash.


Example of error handling:

When handling errors, the mechanism generally used is that Zend Engine will set a jump address. Once exit or die or any serious error E_ERROR occurs, a longjmp() will be used to jump to this address. But this approach will almost always lead to memory leaks. Because all free operations will be skipped. (This problem also exists in C++. When designing a class, never write error handling or warning functions in the constructor or destructor. For the same reason, since the object is already in the destruction or creation stage, So any error function handling may interrupt this process, which may lead to memory leaks). The following code gives an example of this:
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);//创造一个函数名的副本
    zend_str_tolower(lcase_fname, fname_len);//都转换成小写,这样的寻找的时候很方便,这应该也是php函数表中进行函数标识的方式。
    if (zend_hash_find(EG(function_table),
            lcase_fname, fname_len + 1, (void **)&fe) == FAILURE) {?SUCCESS。这个是要在函数表里面寻找待调用的函数。
        zend_execute(fe->op_array TSRMLS_CC);
    } else {
              php_error_docref(NULL TSRMLS_CC, E_ERROR,
                         "Call to undefined function: %s()", fname); //等同于Trigger_error() 
    }
    efree(lcase_fname);
}
Copy after login
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 must be converted to lowercase letters, which can improve the efficiency of the search. If the function to be called is found through the zend_hash_find function, zend_execute is used to call it. And if haunted is not found, an error message will pop up, indicating that it is not found. But here comes the problem. Note that a lowercase version of the function name string was created before to find the function. This string is used until the zend_hash_find function is used. Once it is not found and an error is reported, the memory space corresponding to this string will inevitably not be found, which causes a memory leak.

Therefore, php provides Zend memory management, Zend memory management is also called ZendMM.
  • 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 will also control the memZ specified in the ini file? http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcnlfbGltaXSjrNKyvs3Kx8u10ru1qcO/uPbH68fzy /nSqsfztcTE2rTms6y5/cHL1eK49m1lbW9yeSBsaW1pdKOsxMfDtNKyu+HJ6sfryqew3KGjPGxpPtTazbzW0LXE1+7PwsPmv7S1vcHLy/zT67LZ1/fPtc2zz+DBqs+1tcTSu7LjoaPV67bU stnX98+1zbPW0LXEserXvLXExNq05snqx+u6zcrNt8W1xLe9t6ijrHBocNbQtrzT0LbU06a1xLqvyv2ho9Xi0Km6r8r9sqKyu8rH0ru49rzytaW1xMzmu7ujrMv8w8fW0LD8uqzT0MzYt qi1xNDFz6KjrNTa1eLQqdDFz6K1xLDv1vrPwr7NxNy5u7DRw7+49sfrx/PL+cnqx+u1xMT atOa/6b340NCx6sq2oaPV4tH5vs3E3Lm7yrXP1rbUw7+49sfrx/O1xMTatObH+NPyvfjQ0L fWsfC1xLncwO2hozxsaT7NrMqx1NrNvNbQv7S1vcHL0ru5ssG91tbE2rTmx+vH87XEt73KvaO6cGVyc2lzdGVudLrNcGVyLXJlcXVlc3SjrLbU09pwZXJzaXN0ZW50wLTLtbLu sru24Lj6z7XNs7XEx+vH877N0rvR+cHLo6zSsr7NysfLtcrHtsDBotTaw7/Su7j2x+vH89auz eK1xKOssru74dTax+vH873hyvjWrrrzsbu72MrVoaO1q8rH09DKsbryyse38XBlcnNpc3Rlbn S/ycTc0qpydW50aW1lssXE3NaqtcCjrMv50tTU2tXi1tbH6b /2z8KjrNDo0qrSu7j2ZmxhZ8C01rjKvtXi0ru146GjttTT2srHt/HKx3BlcnNpc3RlbnSjrL340NDE2rTmx+vH87XEt73KvcrHsrvSu9H5tcSho8/Cw+a4+LP2ttTTprnYz7WjugoKPHVs Pgo8bGk+cGVtYWxsb2MoYnVmZmVyX2xlbiwxKSA9PSBtYWxsb2MoYnVmZmVyX2xlbik8bGk+cGVybWFsbG9jKGJ1ZmZlcl9sZW4sMCkgPT0gZW1hbGxvYyhidWZmZXJfbGVuKdXi1t bBqs+1ysfTw7rqtqjS5bXEt73Kvb72tqi1xDxsaT4jZGVmaW5lIHBlbWFsbG9jKHNpemUscGVyc2lzdGVudCkgXDxsaT4KCgo8bGk+Cjx1bD4KKChwZXJzaXN0ZW50KT9tYWxsb2Moc 2l6ZSk6ZW1hbGxvYyhzaXplKSkKCmZsYWc9MbHtyr7Kx3BlcnNpc3RlbnS1xKOszqowse3Kv rK7ysejrL7NuPrSu7DjtcS4vcr009rH68fztcRlbWFsbG9j0rvR+chHLoaMKPGJyPgoKCjxic j4KCs/CzbzW0L/J0tS/tLW9z7XNs7XExNq05snqx+u6r8r90+twaHDW0LXExNq05snqx+u6r8r9tcS21LHI16q7u828o7oKCjxpbWcgc3JjPQ=="http://www.Bkjia.com/uploadfile/Collf iles /20131213/20131213091641239.jpg" alt="">
    If you are not familiar with functions such as malloc, calloc and realloc, please move on: http://www.cppblog.com/sandywin/archive/2011/09/14/155746.html
    In addition, there are two safe mode memory functions: 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 apply for is size*count + addtl. The reason for its existence is to avoid int type overflow.


    Next, let’s talk about a more interesting one, reference counting in php:
    Quotes are found in many languages ​​and are used in many situations. Using references saves space because sometimes it is not necessary to make a copy of each variable. The so-called reference counting refers to how many variables refer to the same memory space, so as to avoid possible memory error operations. First look at the following piece 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);
    	* }
    
    Copy after login
    This code first declares a zval variable, then initializes it with MAKE_STD_ZVAL, and then uses ZVAL_STRING to attach the initial value. Then for this variable, two variable names are given. The first one is a, the second one is b, and there is no doubt that the second one is definitely a reference. But there must be a problem with this code. The problem is that you did not update the corresponding reference count after using zend_hash_add. zend does not know that you have added such an extra reference, which may result in two releases when releasing the memory.所以经过修改之后的正确代码如下:
    	* {
    	*     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);
    	*     <strong>ZVAL_ADDREF(helloval);</strong>//加上这个之后,就不会有重新释放同一块内存空间这样的错误了
    	*     zend_hash_add(EG(active_symbol_table), "b", sizeof("b"),
    	*                                            &helloval, sizeof(zval*), NULL);
    	* }
    
    Copy after login
    进行了ZVAL_ADDREF之后,下一次unset变量的时候,会先查看ref_count引用计数,如果=1就释放,如果>1就只是-1,并不进行内存释放。
    Copy on Write 再来看下面的这一段php代码:
    <?php
        $a = 1;
        $b = $a;
        $b += 5;
    ?>
    Copy after login
    很显然在第二行的时候b声明了一个a的引用,那么在执行完了第三行的代码之后,b增加了,a增不增加呢?很多时候可能并不想增加。所以这个时候当Zend检测到refCount>1之后,就会执行一个变量分离的操作,把原来的一块内存变成两块内存:
    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) {
           /*符号表里没找到 */
           return NULL;
       }
       if ((*varval)->refcount < 2) {
           /* varname 是唯一的引用,什么也不用做 */
           return *varval;
       }
       /* 否则的话,不是唯一的引用,给zval*做一个副本 */
           MAKE_STD_ZVAL(varcopy);
           varcopy = *varval;
       /* Duplicate any allocated structures within the zval* */
           zval_copy_ctor(varcopy); //这一块是怎么拷贝的?mark 应该已经跟varval对应的varname连起来了
       /* 把varname的版本删掉,这会减少varval的引用次数 */
           zend_hash_del(EG(active_symbol_table), varname, varname_len + 1);
       /* 初始化新创造的值的引用次数,然后附给varname变量 */
           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;
    }
    Copy after login
    首先看到了两个判断语句,第一个判断语句先在符号表里面看看有没有找到相应的变量,如果没找到也就没必要分离了。第二个判断语句是看输入的变量的引用次数是不是小于2,如果是的话那就说明输入变量*varval是唯一的,也没必要分离。 否则的话肯定有引用,这个时候就要制作一个副本varcopy。这个副本会承袭varname对应的值,但是不同之处在于帮它重新申请了内存空间,重新初始化了refcount和is_ref参数。 以a、b为例,在$b+=5,执行之后,b作为varname去寻找是否有引用,发现还有一个引用a,这个时候就把b的值拷出来,然后重新申请一片空间,在重新注册为b。这样的话就是两块独立的内存块了。

    Change on Write 再看一个代码片段:
    <?php
        $a = 1;//执行完这一句之后,a变量的ref_count是1,is_ref是0
        $b = &$a;//这一句之后,变量(zval*)的ref_count是2,然后由于显示的&,is_ref为1
        $b += 5;// 这个时候在执行这一句的时候就不会有任何的分离
    ?>
    Copy after login
    如果你觉得想要a跟着b一起改变,那没有问题,只要显式的用&符号进行引用声明就可以了。这样的话is_ref标志位就会被置1. 这时候也就没必要进行内存块的分离了。所以在上面的代码中要把第二个if语句的判断更改一下:
    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;
    }
    Copy after login


    再看最后一种情况,这种情况最纠结:
    <?php
        $a = 1;
        $b = $a;
        $c = &$a;
    ?>
    Copy after login
    既不是copy on write也不是change on wirte,那没办法了,只好分离一下。这里只好b独立出来了:







    对php内存管理的一些机制就说到这里,感觉php确实是一门相当神奇的语言。哈哈。

    www.bkjia.comtruehttp://www.bkjia.com/PHPjc/621625.htmlTechArticlephp对内存的管理机制相当的详尽,它在这一点上更类与java的垃圾回收机制。而对于c语言或者c大部分时候都只能由程序员自己把申请的空间...
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1664
14
PHP Tutorial
1269
29
C# Tutorial
1248
24
Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

PHP Program to Count Vowels in a String PHP Program to Count Vowels in a String Feb 07, 2025 pm 12:12 PM

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Explain late static binding in PHP (static::). Explain late static binding in PHP (static::). Apr 03, 2025 am 12:04 AM

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? What are PHP magic methods (__construct, __destruct, __call, __get, __set, etc.) and provide use cases? Apr 03, 2025 am 12:03 AM

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.

PHP and Python: Comparing Two Popular Programming Languages PHP and Python: Comparing Two Popular Programming Languages Apr 14, 2025 am 12:13 AM

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP in Action: Real-World Examples and Applications PHP in Action: Real-World Examples and Applications Apr 14, 2025 am 12:19 AM

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP: A Key Language for Web Development PHP: A Key Language for Web Development Apr 13, 2025 am 12:08 AM

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

The Enduring Relevance of PHP: Is It Still Alive? The Enduring Relevance of PHP: Is It Still Alive? Apr 14, 2025 am 12:12 AM

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

See all articles