PHP의 메모리 관리자는 계층적입니다. 이 관리자에는 저장 계층, 힙 계층 및 emalloc/efree 계층의 세 가지 계층이 있습니다. 저장 계층은 실제로 malloc(), mmap() 등의 함수를 통해 시스템에서 메모리를 적용하고, free() 함수를 통해 요청된 메모리를 해제한다.
여기서 적용되는 대용량 메모리는 일반적으로 스토리지 계층에서 적용되는 메모리 블록이 상대적으로 큽니다. 단지 힙 계층에서 할당을 호출할 때의 대용량 메모리를 의미하는 것은 아닙니다. 저장 계층의 방법은 분할되어 있으며 형식에 따라 요청되는 메모리가 상대적으로 크고 저장 계층의 역할은 메모리 할당 방법을 힙 계층에 투명하게 만드는 것입니다.
먼저 Storage 계층의 구조를 살펴보면:
<ol class="dp-xml"> <li class="alt"><span><span>/* Heaps with user defined storage */ </span></span></li> <li><span>typedef struct _zend_mm_storage zend_mm_storage; </span></li> <li class="alt"><span> </span></li> <li><span>typedef struct _zend_mm_segment { </span></li> <li class="alt"><span> size_t size; </span></li> <li><span> struct _zend_mm_segment *next_segment; </span></li> <li class="alt"><span>} zend_mm_segment; </span></li> <li><span> </span></li> <li class="alt"><span>typedef struct _zend_mm_mem_handlers { </span></li> <li><span> const char *name; </span></li> <li class="alt"><span> zend_mm_storage* (*init)(void *params); //初始化函数 </span></li> <li><span> void (*dtor)(zend_mm_storage *storage); //析构函数 </span></li> <li class="alt"><span> void (*compact)(zend_mm_storage *storage); </span></li> <li><span> zend_mm_segment* (*_alloc)(zend_mm_storage *storage, size_t size); //内存分配函数 </span></li> <li class="alt"><span> zend_mm_segment* (*_realloc)(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size); //重新分配内存函数 </span></li> <li><span> void (*_free)(zend_mm_storage *storage, zend_mm_segment *ptr); //释放内存函数 </span></li> <li class="alt"><span>} zend_mm_mem_handlers; </span></li> <li><span> </span></li> <li class="alt"><span>struct _zend_mm_storage { </span></li> <li><span> const zend_mm_mem_handlers *handlers; //处理函数集 </span></li> <li class="alt"><span> void *data; </span></li> <li><span>}; </span></li> </ol>
메모리 할당 방식, 호출되는 함수는 _zend_mm_storage 구조에 설정된 처리 함수이고, 메모리는 세그먼트의 형태.
4가지 메모리 체계
PHP에는 스토리지 계층에 malloc, win32, mmap_anon, mmap_zero의 4가지 메모리 할당 체계가 있습니다. 기본적으로 메모리 할당에는 malloc이 사용된다. ZEND_WIN32 매크로를 설정하면 Windows 버전이고 HeapAlloc을 호출해 메모리를 할당한다. 나머지 2개의 메모리 체계는 익명 메모리 매핑이며, PHP의 메모리 체계는 변수 설정을 통해 수정할 수 있다. .
공식 설명은 다음과 같습니다.
Zend MM은 ZEND_MM_MEM_TYPE 및 ZEND_MM_SEG_SIZE 환경 변수를 사용하여 조정할 수 있습니다. 기본값은 "malloc" 및 "256K"입니다. 대상 시스템에 따라 다릅니다. "mmap_anon", "mmap_zero" 및 "win32" 스토리지 관리자를 사용할 수도 있습니다.
코드에서 이러한 네 가지 메모리 할당 방식에 대해 zend_mm_mem_handlers의 각 처리 함수가 각각 구현됩니다. 일치하는 코드에 대한 간단한 설명은 다음과 같습니다.
<ol class="dp-xml"> <li class="alt"><span><span>/* 使用mmap内存映射函数分配内存 写入时拷贝的私有映射,并且匿名映射,映射区不与任何文件关联。*/ </span></span></li> <li><span># define ZEND_MM_MEM_MMAP_ANON_DSC {"mmap_anon", zend_mm_mem_dummy_init, zend_mm_mem_dummy_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_mmap_anon_alloc, zend_mm_mem_mmap_realloc, zend_mm_mem_mmap_free} </span></li> <li class="alt"><span> </span></li> <li><span>/* 使用mmap内存映射函数分配内存 写入时拷贝的私有映射,并且映射到/dev/zero。*/ </span></li> <li class="alt"><span># define ZEND_MM_MEM_MMAP_ZERO_DSC {"mmap_zero", zend_mm_mem_mmap_zero_init, zend_mm_mem_mmap_zero_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_mmap_zero_alloc, zend_mm_mem_mmap_realloc, zend_mm_mem_mmap_free} </span></li> <li><span> </span></li> <li class="alt"><span>/* 使用HeapAlloc分配内存 windows版本 关于这点,注释中写的是VirtualAlloc() to allocate memory,实际在程序中使用的是HeapAlloc*/ </span></li> <li><span># define ZEND_MM_MEM_WIN32_DSC {"win32", zend_mm_mem_win32_init, zend_mm_mem_win32_dtor, zend_mm_mem_win32_compact, zend_mm_mem_win32_alloc, zend_mm_mem_win32_realloc, zend_mm_mem_win32_free} </span></li> <li class="alt"><span> </span></li> <li><span>/* 使用malloc分配内存 默认为此种分配 如果有加ZEND_WIN32宏,则使用win32的分配方案*/ </span></li> <li class="alt"><span># define ZEND_MM_MEM_MALLOC_DSC {"malloc", zend_mm_mem_dummy_init, zend_mm_mem_dummy_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_malloc_alloc, zend_mm_mem_malloc_realloc, zend_mm_mem_malloc_free} </span></li> <li><span> </span></li> <li class="alt"><span>static const zend_mm_mem_handlers mem_handlers[] = { </span></li> <li><span>#ifdef HAVE_MEM_WIN32 </span></li> <li class="alt"><span> ZEND_MM_MEM_WIN32_DSC, </span></li> <li><span>#endif </span></li> <li class="alt"><span>#ifdef HAVE_MEM_MALLOC </span></li> <li><span> ZEND_MM_MEM_MALLOC_DSC, </span></li> <li class="alt"><span>#endif </span></li> <li><span>#ifdef HAVE_MEM_MMAP_ANON </span></li> <li class="alt"><span> ZEND_MM_MEM_MMAP_ANON_DSC, </span></li> <li><span>#endif </span></li> <li class="alt"><span>#ifdef HAVE_MEM_MMAP_ZERO </span></li> <li><span> ZEND_MM_MEM_MMAP_ZERO_DSC, </span></li> <li class="alt"><span>#endif </span></li> <li><span> {NULL, NULL, NULL, NULL, NULL, NULL} </span></li> <li class="alt"><span>}; </span></li> </ol>
1