Detailed explanation of php memory management
In C, malloc and free are used directly to allocate and release memory. However, frequent allocation and release of memory will cause memory fragmentation and reduce system performance. PHP variables will be allocated and released very frequently. If you directly use malloc Allocating in this way will cause serious performance problems. As a language-level application, this loss is not acceptable, so PHP implemented its own memory pool ZendMM to replace glibc's malloc and free to solve the problem of frequent memory allocation. , the issue of release.
It defines memory operations at three granularities: chunk, page, and slot. The size of each chunk is 2MB, and each page is 4kB. One chunk is cut into 512 pages, and each page is cut into several slots to apply for memory. Different allocation strategies are implemented according to the size of the application.
huge: larger than 2MB, directly call the system allocation, allocate several chunks
large: apply for memory larger than 3092B (3/4page), smaller than 2044kb (511page) allocation Several pages
small: The application memory is less than 3092B. The memory pool has defined 30 different sizes of memory (8, 16, 32..., 3072) in advance. They are distributed on different pages. When applying for memory, you can directly Find the corresponding slot on the corresponding memory. The memory pool stores the main information of the memory pool through the zend_mm_heap structure, such as large memory linked list, chunk linked list, memory linked list of each slot size, etc.
Large memory is actually allocated to several chunks. Then it is managed through a zend_mm_huge_list structure. A one-way linked list is formed between large memories.
Chunk is the minimum granularity for the memory pool to apply for and release memory from the system. A doubly linked list is formed between chunks. The address of the first chunk is stored in zend_mm_heap- >main_chunk, the memory of the first page is used to save the structure members of the chunk itself, such as the pointers of the previous and next chunks, the usage of each page of the current chunk, etc.
Slots of the same size form a singly linked list
The initialization of the memory pool is completed in the php_module_startup stage. The initialization process is mainly to allocate the heap structure. This process is completed in the start_memory_manager process. If it is a multi-threaded environment, a memory pool will be allocated for each thread, and the threads will not affect each other. During initialization, the environment variable use_zend_alloc_huge_pages will be used to set whether to enable memory huge pages. In a non-thread-safe environment, the allocated heap will be saved in alloc_globals, which is the AG macro. It should be noted that the zend_mm_heap structure is not allocated separately and is embedded in In the chunk structure, because the chunk structure occupies a page, but in fact it does not use that much memory, in order to utilize the space as much as possible, it is placed here
Memory allocation: 1. Huge memory allocation exceeding 2MB will be aligned to n chunks when allocated, and a zned_mm_huge_list structure will also be allocated to manage all huge memory. The memory alignment process is adjusted by the memory pool itself after application, not simply It is completed by the operating system. It will apply once according to the actual size. If the memory alignment can just be achieved, no adjustment is needed and it will be returned to use directly. If it is not an integer multiple of ZEND_MM_CHUNK_SIZE (2MB), zendMM will release the memory and then follow the instructions. Actual memory size + ZEND_MM_CHUNK_SIZE Apply again. The extra block is used for adjustment. 2. Large allocation: When the applied memory size is between 3072B (3/4page) and 2044k (511 pages), the memory pool will be in Search the corresponding number of pages on the chunk and return it. The application granularity of large is page. There are two members, free_map and map, on the chunk to record the allocation information of the page.
free_map is 512bit, which is used to record the allocation of pages on the chunk. Set to 1 if used Start traversing from the first chunk and check whether the chunks have pages that meet the requirements. If the current chunk does not have a suitable page, then search for the next chunk. If there is no suitable one until the end, then re-allocate a chunk. When applying, I don’t know Whoever finds a sufficient number of pages should fill the chunk gaps as much as possible and connect them with the allocated pages as much as possible to avoid page gaps in the middle (to reduce the number of searches during subsequent allocation) 1) From The first chunk group (0~63) starts to check. There are available pages in the current group. First check the bits of the current page and find the positions of the first and last free pages. If there are not enough, mark these pages as 1 ( Allocated), search for other groups. If the page is just right, use it directly and interrupt the retrieval. If the page is larger than required, it means it is available, but it is not optimal. It will continue to search for other chunks until an optimal one is finally found ( can maximize the use of the page) 2) After finding the appropriate page, set the corresponding page information, that is, free_map and map information, and then return the page address 3. Small allocation:
will first check whether the memory of the corresponding specifications has been allocated. If it is not allocated or the allocation has been used up, apply for the corresponding number of pages. The page allocation process is the same as that of large allocation. After applying for the page, it is cut into slots according to the fixed size. The slots are connected with a single linked list, and the head of the linked list is saved. To AG(mm_heap)->free_slot
The granularity of memory pool release is chunk, which is completed through efree. 1. The release of huge, large, and small memory types is because the first page of the chunk is occupied, so it is impossible to have an offset of 0 relative to the chunk, so it can be distinguished When releasing the chunk type and the large and small types, the occupied chunk will be released and deleted from the AG linked list at the same time. 2. Release of large memory: If the calculated offset is not 0, it means that the address is large or small memory, and then according to The offset calculates the page number. After getting the page, you can get the allocation type of the page from the chunk->map, and you can release the memory of the specified type. Large will not release it directly, but will set the allocation information of the page to Unallocated. If it is found that the chunk is unallocated after release, the chunk will be released. When releasing, it is preferred to move the chunk to AG. After the cache number reaches a certain value, the newly added chunk will no longer be cached and the memory will be returned. System, avoid occupying too much memory. When allocating chunks, if a cached chunk is found in chached_chunks, it can be directly taken out and used without making an application to the system. 3. Small type release, directly insert the released slot back into the available linked list of the rule slot. Just the head, relatively simple
In C, malloc and free are used directly to allocate and release memory. However, frequent allocation and release of memory will cause memory fragmentation and reduce system performance. PHP variables will be allocated and released very frequently. If you directly use malloc Allocating in this way will cause serious performance problems. As a language-level application, this loss is not acceptable, so PHP implemented its own memory pool ZendMM to replace glibc's malloc and free to solve the problem of frequent memory allocation. , Release issues
It defines memory operations at three granularities: chunk, page, and slot. The size of each chunk is 2MB, and each page is 4kB. A chunk is cut into 512 pages, and each page is cut. into several slots. When applying for memory, different allocation strategies are implemented according to the size of the application.
huge: greater than 2MB, directly call the system allocation, allocate several chunks
large: apply for memory greater than 3092B (3/4page) , less than 2044kb (511page) allocate several pages
small: apply for memory less than 3092B, the memory pool has defined 30 different sizes of memory in advance (8, 16, 32..., 3072), they are distributed in different On the page, when applying for memory, directly search the corresponding slot in the corresponding memory. The memory pool stores the main information of the memory pool through the zend_mm_heap structure, such as large memory linked list, chunk linked list, memory linked list of each slot size, etc.
Large memory allocation It is actually several chunks, which are then managed through a zend_mm_huge_list structure. A one-way linked list is formed between large memories.
Chunk is the minimum granularity for the memory pool to apply for and release memory from the system. A two-way linked list is formed between chunks. The first The address of the chunk is stored in zend_mm_heap->main_chunk. The memory of the first page is used to save the structure members of the chunk itself, such as the pointers of the previous and next chunks, the usage of each page of the current chunk, etc.
Between slots of the same size Forming a single linked list
The initialization of the memory pool is completed in the php_module_startup stage. The initialization process is mainly to allocate the heap structure. This process is completed in the start_memory_manager process. If it is a multi-threaded environment, a memory pool will be allocated for each thread. Threads do not affect each other. During initialization, the environment variable use_zend_alloc_huge_pages will be used to set whether to enable memory huge pages. In a non-thread-safe environment, the allocated heap will be saved in alloc_globals, which is the AG macro. It should be noted that the zend_mm_heap structure It is not allocated separately, but is embedded in the chunk structure, because the chunk structure occupies a page, but in fact it does not use that much memory. In order to utilize the space as much as possible, it is placed here
Memory allocation: 1. Huge memory allocation exceeding 2MB will be aligned to n chunks when allocated, and a zned_mm_huge_list structure will also be allocated to manage all huge memory. The memory alignment process is the memory pool itself after application The adjustment is not simply done by the operating system. It will be applied once according to the actual size. If the memory alignment can just be achieved, no adjustment is needed and it will be returned to use directly. If it is not an integer multiple of ZEND_MM_CHUNK_SIZE (2MB), zendMM will release it. For this piece of memory, apply again according to the actual memory size + ZEND_MM_CHUNK_SIZE. The extra piece of memory applied for is used for adjustment. 2. Large allocation: The applied memory size is between 3072B (3/4page) and 2044k (511 pages). time, the memory pool will search for the corresponding number of pages on the chunk and return them. The application granularity of large is page. There are two members free_map and map on the chunk to record the allocation information of the page.
free_map is 512bit, which is used to record the page. The allocation status of the page on the chunk. If it is used, it is set to 1
. The map is used to record the allocation type of the page and the number of allocated pages. Each page corresponds to an array member. The highest 2 bits record the allocation type of the page. 01 is Large and 10 are small. When allocating, start traversing from the first chunk and check whether the chunk has a page that meets the requirements. If the current chunk does not have a suitable page, search for the next chunk. If there is no suitable page until the end, reallocate it. When applying for a chunk, I don’t know who has found enough pages, but fill the gaps in the chunk as much as possible, and connect them with the allocated pages as much as possible to avoid page gaps in the middle (to reduce the time of subsequent allocation) The number of searches) 1) Start checking from the first chunk group (0~63). If the current group has available pages, first detect the bits of the current page and find the positions of the first and last free pages. If there are not enough, then These pages are marked as 1 (allocated), and other groups are searched. If the page is just right, it is used directly and the retrieval is interrupted. If the page is larger than required, it means it is available, but it is not optimal, and other chunks will be searched until the end. Compare the optimal one (the one that can maximize the use of the page) 2) After finding the appropriate page, set the corresponding page information, that is, free_map and map information, and then return the page address 3. Small allocation:
will check the corresponding first Whether the specified memory has been allocated? If it has not been allocated or the allocation has been used up, apply for pages with the corresponding number of pages. The page allocation process is the same as that of large allocation. After applying for the page, it is cut into slots according to the fixed size, and the slots are divided into single slots. Linked list connection, the head of the linked list is saved to AG(mm_heap)->free_slot
The granularity of memory pool release is chunk, which is completed through efree. 1. The release of huge, large, and small memory types is because the first page of the chunk is occupied, so it is impossible to have an offset of 0 relative to the chunk, so it can be distinguished When releasing the chunk type and the large and small types, the occupied chunk will be released and deleted from the AG linked list at the same time. 2. Release of large memory: If the calculated offset is not 0, it means that the address is large or small memory, and then according to The offset calculates the page number. After getting the page, you can get the allocation type of the page from the chunk->map, and you can release the memory of the specified type. Large will not release it directly, but will set the allocation information of the page to Unallocated. If it is found that the chunk is unallocated after release, the chunk will be released. When releasing, it is preferred to move the chunk to AG. After the cache number reaches a certain value, the newly added chunk will no longer be cached and the memory will be returned. System, avoid occupying too much memory. When allocating chunks, if a cached chunk is found in chached_chunks, it can be directly taken out and used without making an application to the system. 3. Small type release, directly insert the released slot back into the available linked list of the rule slot. Just the head, relatively simple.
Related recommendations:
Explanation of JS memory management examples
Detailed introduction to memory management in Linux
Study notes on PHP variables and memory management
The above is the detailed content of Detailed explanation of php memory management. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











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,

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

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 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 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 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 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

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.
