下面先看一下内存的一些变化过程:
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img2.ph.126.net/qHAbRbqtkz6lgGzkk47RzQ==/6597570044448678923.jpg)
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img0.ph.126.net/bMeAaI4TzGsf8rtRsIg-OQ==/3157586288840294295.jpg)
为什么,unset释放内存后,与第一次输出的不一样呢。其实是输出函数占用了部分内存。
下面我们在看下:
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img0.ph.126.net/Bt1FA90lHwYrUX5KKhF-fw==/1888134143875234653.jpg)
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img1.ph.126.net/lyDpn4804_tOoHqC43A-uw==/1892356268525912308.jpg)
这样内存就相同了。。
PHP的unset确实会释放内存(当然, 还要结合引用和计数), 但这个释放不是C编程意义上的释放, 不是交回给OS。
对于PHP来说, 它自身提供了一套和C语言对内存分配相似的内存管理API。
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img0.ph.126.net/V17ZzHWuZYT07Q9KA6JfYg==/6597933982797473202.jpg)
这些API和C的API意义对应, 在PHP内部都是通过这些API来管理内存的。
当我们调用emalloc申请内存的时候,PHP并不是简单的向OS要内存,而是会像OS要一个大块的内存,然后把其中的一块分配给申请者, 这样当再有逻辑来申请内存的时候,就不再需要向OS申请内存了,避免了频繁的系统调用。
eg:
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img1.ph.126.net/SXOtJPW0zMrI8KEQpXXDsw==/3167437913025181678.jpg)
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img1.ph.126.net/gCiTLGUmBpt2iK1xhoEwTQ==/6597598631750997778.jpg)
同样的, 在我们调用efree释放内存的时候, PHP也不会把内存还给OS,,而会把这块内存,,归入自己维护的空闲内存列表.,而对于小块内存来说,,更可能的是, 把它放到内存缓存列表中去。
关于数组的内存分配:
Hashtable是PHP的核心结构,数组也是用它来表示的,而符号表也是一种关联数组, 对于如下代码:
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img0.ph.126.net/isLO_KGy4Emr_JdCcT_41A==/3393743794300485219.jpg)
我们定义了100个变量, 然后又Unset了他们,,来看看输出:
![浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin 浅谈PHP内存分配管理机制 - kaizhu_QIN - kaizhu_Qin](http://img0.ph.126.net/GCv_c-OK67DEFgyd16Ik8w==/1686035110596981960.jpg)
这是因为对于Hashtable来说,定义它的时候,不可能一次性分配足够多的内存块,来保存未知个数的元素,,所以PHP会在初始化的时候, 只是分配一小部分内存块给HashTable,,当不够用的时候再RESIZE扩容。
而Hashtable, 只能扩容,不会减少,对于上面的例子,当我们存入100个变量的时候, 符号表不够用了,做了一次扩容, 而当我们依次unset掉这100个变量以后,变量占用的内存是释放了(334172– 325752),但是符号表并没有缩小,所以这些少的内存是被符号表本身占去了....