Several difficult points in memory management of PHP principles

Source: Internet
Author: User
The memory management of PHP is divided into two major parts. The first part is the memory management of PHP. The main content of this part is reference counting, write-time replication, and other application-oriented management. the second part is what I will introduce Today. the content about PHP in zend_alloc is... "> <LINKhref =" http://www.php100.com//statics/

 

The memory management of PHP is divided into two major parts. The first part is the memory management of PHP. The main content of this part is reference counting, write-time replication, and other application-oriented management. the second part is what I will introduce Today. the zend_alloc describes the memory management of PHP itself, including how it manages available memory and how to allocate memory.

In addition, why do we need to write this statement, because there is no reference to the policies, data structures, or algorithms used in PHP memory management. while we develop extensions and fix PHP bugs, we need a good understanding of this part of knowledge. many friends in the PHP development team are not very clear about this, so I think it is necessary to write it specially.

I will not go into details about some basic concepts, because it is easy to understand the code. here I will mainly introduce some points that are not easy to understand. why, before I wrote an article, I searched for the existing materials to avoid repeated efforts. I saw the TIPI project's description of this part and found many errors. therefore, I think this part is not easy to understand.

 

At present, the English version is also being written: Zend MM

Zend Memory Manager (Zend MM) is the Memory management logic in PHP. it has a key data structure: zend_mm_heap:

  

 

Zend MM treats memory instead of small memory and large memory separately. for small memory, this part is the most commonly used, so it pursues high performance. for large memory, the pursuit is to be secure and avoid memory waste as much as possible.

Therefore, for small memory, PHP also introduces the cache mechanism:

  

 

Zend MM tries its best to use the cache to locate the allocation.

What is not easy to understand is the statement of free_buckets:

Q: Why is the length of the free_buckets array ZEND_MM_NUMBER_BUCKET?

A: This is because PHP uses A fixed-length array to store ZEND_MM_NUMBER_BUCKET zend_mm_free_block, as shown in the red box. for an unused free_buckets element, the only useful data structures are next_free_block and prev_free_block. to save memory, PHP does not allocate ZEND_MM_NUMBER_BUCKET * sizeof (zend_mm_free_block) memory, instead, it only uses the memory size of ZEND_MM_NUMBER_BUCKET * (sizeof (* next_free_block) + sizeof (* prev_free_block ..

Let's take a look at the definition of ZEND_MM_SMALL_FREE_BUCKET macro:

# Define ZEND_MM_SMALL_FREE_BUCKET (heap, index )\
(Zend_mm_free_block *) (char *) & heap-> free_buckets [index * 2] + \
Sizeof (zend_mm_free_block *) * 2 -\
Sizeof (zend_mm_small_free_block ))

Then, Zend MM ensures that only the prev and next pointers will be used, so it will not cause memory read errors ..

The second difficulty is that PHP manages large_free_buckets and first introduces allocation (the TIPI project team's description of this part is vague ):

Static zend_mm_free_block * zend_mm_search_large_block (zend_mm_heap * heap, size_t true_size)

Large_free_buckets can be said to be a combination of achievements and two-way lists:

  

 

Large_free_buckets uses a macro to determine the memory size and index of the memory:

# Define ZEND_MM_LARGE_BUCKET_INDEX (S) zend_mm_high_bit (S)

Zend_mm_high_bit: obtains the serial number (zend_mm_high_bit) of the highest bit 1 in true_size. the corresponding assembly command is bsr (here, the TIPI project error description is: "This hash function is used to calculate the number of digits of size, the return value is the number of 1 in the size binary code-1 ″).

That is to say, every element in large_free_buckets points to a memory block with the size of 1 at the corresponding index. it is a bit of a detour. for example:

For example, for large_free_buckets [2], it will only be saved, with the memory size ranging from 0b1000 to 0b1111. for another example, large_free_buckets [6] stores a pointer of memory sizes from 0b0000000 to 0b11111111.

In this way, Zend MM can quickly locate the most suitable region when allocating memory to improve performance.

Each element is a two-way list at the same time, keeping the same size of memory blocks, while the left and right children (child [0] and child [1]) it represents the key values 0 and 1 respectively. what does this key value mean?

Let's take an example. for example, I applied for a true_size 0 b11010 memory from PHP. after some steps, I did not find a suitable memory, PHP enters the logic of zend_mm_search_large_block to find the appropriate memory in large_free_buckets:

1. First, calculate the index corresponding to true_size. the calculation method is as follows: ZEND_MM_LARGE_BUCKET_INDEX

2. Then, in a bitmap structure, determine whether an available memory larger than true_size already exists in large_free_buckets. if not, return:

Size_t bitmap = heap-> large_free_bitmap> index; if (bitmap = 0) {return NULL ;}

3. determine whether free_buckets [index] has available memory:

If (UNEXPECTED (bitmap & 1 )! = 0 ))

4. if it exists, find the most suitable memory starting from free_buckets [index]. The steps are as follows:

4.1. starting from free_buckets [index], if the current memory size of free_buckets [index] is equal to true_size, the search ends and a success is returned.

4.2. view the current highest bit after the index (true_size <(ZEND_MM_NUM_BUCKETS-index) corresponding to true_size, if it is 1. continue searching under free_buckets [index]-> child [1]. if free_buckets [index]-> child [1] does not exist, the system jumps out. if the current maximum value of true_size is 0, search for it under free_buckets [index]-> child [0]. if free_buckets [index]-> child [0] does not exist, find the minimum memory under free_buckets [index]-> child [1] (because it can be ensured at this time, the memory in free_buckets [index]-> child [1] is larger than true_size)

4.3. the starting point is changed to the child described in 2, with a ture_size shifted to the left.

5. if the above logic does not find the appropriate memory, find the smallest "large memory ":

/* Search for smallest "large" free block */
Best_fit = p = heap-> large_free_buckets [index + zend_mm_low_bit (bitmap)];
While (p = p-> child [p-> child [0]! = NULL]) {
If (ZEND_MM_FREE_BLOCK_SIZE (p) <ZEND_MM_FREE_BLOCK_SIZE (best_fit )){
Best_fit = p;
}
}

Note the above logic, (p = p-> child [p-> child [0]! = NULL]), PHP tries its best to find the smallest memory.

Why is large_free_buckets a Key tree? from the logic above, we can see that PHP makes a size key according to binary 0, 1, and reflects the memory size information to the key tree, this facilitates quick search.

In addition, there is another rest_buckets structure, which is a two-way list to save some of the remaining memory after PHP allocation, to avoid meaningless performance problems caused by inserting the remaining memory into free_buckets (here, the description of the TIPI project error is: "This is an array with only two elements. Our common insert and search operations target the first element, namely heap-> rest_buckets [0] ").

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.