内存管理概述

内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。

在使用C/C++开发程序的时候,需要格外注意内存管理,申请了内存再使用完后要记得释放,否则可能会造成内存泄漏。如果程序需要常驻内存,那么内存泄漏问题会把机器的内存耗光。所以在PHP这种需要常驻内存的程序来说,内存管理非常重要,它决定了程序的稳定性和执行效率。另外,应用程序向系统申请内存,释放内存的时候会引发系统调用,系统调用提供用户程序与操作系统之间的接口,他会触发0x80 号中断(int 0x80)将CPU从用户态切换到内核态,执行完毕再切换回用户态。在PHP这种对性能要求较高的程序来说,频繁在用户态和内核态切换会带来很大的性能消耗。

介于以上原因,PHP实现了自己的内存管理器(ZendMM), 所以在编写PHP脚本的时候我们不需要对内存进行管理。

ZendMM

Zend Memory Manager
===================

General:
--------

The goal of the new memory manager (available since PHP 5.2) is to reduce memory
allocation overhead and speedup memory management.

PHP的内存管理是分层的,它分为三层:存储层(storage)、堆层(heap)和接口层(emalloc/efree)。存储层通过 malloc()、mmap() 等函数向系统真正的申请内存,并通过 free() 函数释放所申请的内存。存储层通常一次申请大量内存,这样接口层在需要分配空间的时候,通过堆层将存储层申请到的内存进行拆分,按照大小给接口层使用。在存储层共有4种内存分配方案: malloc,win32,mmap_anon,mmap_zero。默认使用malloc分配内存,如果设置了ZEND_WIN32宏,则为windows版本,调用HeapAlloc分配内存。并且PHP的内存方案可以通过设置变量来修改。

the Zend MM can be tweaked using ZEND_MM_MEM_TYPE and ZEND_MM_SEG_SIZE environment
variables.  Default values are "malloc" and "256K". Dependent on target system you
can also use "mmap_anon", "mmap_zero" and "win32" storage managers.

	$ ZEND_MM_MEM_TYPE=mmap_anon ZEND_MM_SEG_SIZE=1M sapi/cli/php ..etc.

借用一张图来说明一下:

Untitled

内存分配有两种类型:

  1. small, 为了速度和效率。
  2. large, 为了不造成浪费。

内存分配有两种生命周期:

  1. request,最常见的情况,只需要满足当前请求的内存需求,一次请求结束之后就free。
  2. persistent,需要被分配比单个请求持续时间更长的一段时间的内存,这种情况下使用操作系统的malloc来分配内存,这些分配的内存并不会添加ZendMM使用的那些额外的信息,从而实现永久分配。

ZendMM提供的request内存分配相关函数:

void*  emalloc(size_t size);
void*  erealloc(void* pointer, size_t size);
void*  ecalloc(size_t num, size_t count);
void   efree(void* pointer);

ZendMM提供的persistent内存分配相关函数:

Powered by Fruition