Elementary Introduction to PHP Source 31: Heap Layer Foundation in PHP memory pool

Source: Internet
Author: User
Tags php source code zend
This article mainly introduces about the PHP source code 31: PHP Memory Pool in the heap stack (heap) Layer Foundation, has a certain reference value, now share to everyone, the need for friends can refer to

Elementary Introduction to PHP Source 31: Heap Layer Foundation in PHP memory pool

Overview
PHP's memory manager is layered (hierarchical). This manager has three tiers: storage layer (storage), heap layer, and emalloc/efree layer. In the PHP source read Note 30: The storage tier in the PHP memory pool describes the storage layer, the storage layer through the malloc (), mmap () and other functions to the system to really request memory, and through the free () function to release the requested memory. Storage layer is usually requested by the memory block is relatively large, where the application of large memory is not refers to the storage layer structure requires large memory, but the heap layer by calling the storage layer allocation method, its format in the form of the memory is relatively large, the role of the storage layer is the way memory allocation to the heap layer transparency.
Above the storage layer is the heap layer we are going to understand today. Heap layer A scheduling layer, which interacts with the emalloc/efree layer above, will be split on demand by the chunk of memory requested by the storage layer. There is a set of memory scheduling policies in the heap layer, which is the core area of the entire PHP memory allocation management.

All of the following shares are based on a case where zend_debug is not open.
First look at the structure involved in the heap layer:
Structure

 /* mm block type */typedef struct _zend_mm_block_info {size_t _size;/* block size */size_t _prev;/* calculate previous block useful to */} Zend_mm_blo  Ck_info; typedef struct _ZEND_MM_BLOCK {zend_mm_block_info info;} zend_mm_block; typedef struct _ZEND_MM_SMALL_FREE_BLOCK {/* doubly linked list */zend_mm_block_info info;struct _zend_mm_free_block *prev_free_ block;/* previous block */struct _zend_mm_free_block *next_free_block;/* after a block */} zend_mm_small_free_block;/* small free block */typedef struct _zend_mm_free_block {/* doubly linked list + tree structure */zend_mm_block_info info;struct _zend_mm_free_block *prev_free_block;/* previous block * /struct _zend_mm_free_block *next_free_block;/* after a block */struct _zend_mm_free_block **parent;/* parent node */struct _zend_mm_   Free_block *child[2];/* Two sub-nodes */} Zend_mm_free_block; struct _ZEND_MM_HEAP {int use_zend_alloc;/* whether to use Zend Memory Manager */void * (*_malloc) (size_t);/* Memory allocation function */void (*_free) (void*);/* Memory release function */void * (*_realloc) (void*, size_t); size_t free _bitmap;/* Small block of free memory ID */size_t             Large_free_bitmap; /* Bulk free Memory ID */size_t block_size;/* The segment size of the memory allocation, that is, the size specified by the zend_mm_seg_size, which defaults to zend_mm_seg_size (. * 1024x768) */size_ T compact_size;/* compress operation boundary value, specify size for zend_mm_compact, default to 2 * 1024x768 * 1024*/zend_mm_segment *segments_list;/* segment Pointer column Table */zend_mm_storage *storage;/* called storage layer */size_t real_size;/* heap true size */size_t real_peak;/* heap True Real-size peak */size_t limit;/* heap memory boundary */size_t size;/* Heap Size */size_t peak;/* Heap Size peak */size_                 T reserve_size;/* standby Heap size */void *reserve;/* alternate heap */int overflow;/* memory Overflow */int internal; #if zend_mm_cacheunsigned int cached;/* cache size */zend_mm_free_block *cache[zend_mm_num_buckets] ;/* Cache array/#endifzend_mm_free_block *free_buckets[zend_mm_num_buckets*2];/* small block of free memory array */zend_mm_free_block *large_free _buckets[zend_mm_num_buckets];/* chunk free Memory array */zend_mm_free_block *rest_buckets[2];/* remaining memory array */};

For memory manipulation functions in the heap structure, if Use_zend_alloc is no, the Malloc-type memory allocation is used, at which time all operations do not go through memory management in the heap layer, directly using malloc and other functions.

The size of the compact_size defaults to 2 * 1024x768 * 1024x768 (2M), if there is a set variable zend_mm_compact the size is specified, if the memory peak exceeds this value, then the storage compact function is called. Only the implementation of this function is now empty and may be added in subsequent versions.

Reserve_size is the size of the standby heap, which by default is Zend_mm_reserve_size, and its size is (8*1024)
The *reserve is a standby heap with a size of reserve_size, which is used as a memory overflow when reporting errors.

"About Use_zend_alloc"
The environment variable Use_zend_alloc can be used to allow the selection of malloc or emalloc memory allocations at run time. Using Malloc-type memory allocation will allow the external debugger to observe memory usage, whereas EMALLOC allocations will use the Zend memory Manager abstraction, which requires internal debugging.
[Zend_startup (), Start_memory_manager (), Alloc_globals_ctor ()]

static void Alloc_globals_ctor (Zend_alloc_globals *alloc_globals tsrmls_dc) {char *tmp;alloc_globals->mm_heap = Zend_mm_startup (); TMP = getenv ("Use_zend_alloc"), if (tmp) {alloc_globals->mm_heap->use_zend_alloc = Zend_atoi (tmp, 0); if (!alloc_ GLOBALS->MM_HEAP->USE_ZEND_ALLOC) {/* If you do not use Zend's memory manager, use the malloc function directly */alloc_globals->mm_heap->_malloc = Malloc;alloc_globals->mm_heap->_free = Free;alloc_globals->mm_heap->_realloc = ReAlloc;}}}

"Initialize"

[Zend_mm_startup ()]
Initializes the allocation scheme for the storage layer, initializes the segment size, compresses the boundary value, and calls ZEND_MM_STARTUP_EX () to initialize the heap layer.

[Zend_mm_startup () ZEND_MM_STARTUP_EX ()]
"Memory Alignment"
Memory alignment is used in the memory allocation of PHP, and there are obviously two targets for memory alignment calculations: One is to reduce the number of CPU visits, and the second is to keep the storage space efficient enough.

# define Zend_mm_alignment 8 #define ZEND_MM_ALIGNMENT_MASK ~ (zend_mm_alignment-1)  #define ZEND_MM_ALIGNED_SIZE ( Size) (((size) + zend_mm_alignment-1) & Zend_mm_alignment_mask)  #define Zend_mm_aligned_header_sizezend_mm_ Aligned_size (sizeof (zend_mm_block)) #define Zend_mm_aligned_free_header_sizezend_mm_aligned_size (sizeof (zend_mm_ Small_free_block))

PHP in the allocation block of memory, with memory alignment, if the required memory size of the lower three bits is not 0 (not divisible by 8), then the lower three bits plus 7, and the same with the operation, that is, the size is not 8 of the integer times the size of the total memory can be divisible by 8.
On the Win32 machine, some macros correspond to a numeric size of:
Zend_mm_min_size=8
zend_mm_max_small_size=272
Zend_mm_aligned_header_size=8
Zend_mm_aligned_free_header_size=16
Zend_mm_min_alloc_block_size=8
Zend_mm_aligned_min_header_size=16
Zend_mm_aligned_segment_size=8

If you are assigning a block of size 9 bytes, the actual allocated size is Zend_mm_aligned_size (9 + 8) =24

"Positioning of Blocks"
The two bits to the right of the allocated memory are the types used to mark the memory.
Its size is defined as # define ZEND_MM_TYPE_MASKZEND_MM_LONG_CONST (0x3)

The code shown below is the positioning of the block

#define Zend_mm_next_block (b) zend_mm_block_at (b, zend_mm_block_size (b)) #define Zend_mm_prev_block (b) zend_mm_block _at (b,-(int) ((b)->info._prev & ~zend_mm_type_mask))  #define ZEND_MM_BLOCK_AT (BLK, offset) ((zend_mm_ Block *) (((char *) (BLK)) + (offset)) #define ZEND_MM_BLOCK_SIZE (b) ((b)->info._size & ~zend_mm_type_mask) # Define ZEND_MM_TYPE_MASKZEND_MM_LONG_CONST (0x3)

The next element of the current block, which is the length of the current block's head position plus the entire block (the length of the type is removed).
The previous element of the current block, which is the length of the head position of the current block minus the previous block (the length of the type is removed).
About the length of the previous block, set the size of the current block to the block type or the result of the operation when the block is initialized.

The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!

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.