php内存管理分为两大部分
一 php 自身的内存管理
面向应用层面的管理,php的内存(1)管理使用的是符号表的思想,符号表(2)是一个数组,此数组将变量名映射到其值在内存中的位置
1 引用计数
1.1 每个php变量都会存在一个叫zval的变量容器中。
此容器包含四部分:
A 变量类型
B 变量值
C is_ref 用来标识是否属于引用集合(reference set),通过这个字节php区分普通变量和引用变量
D refcount 用来表示指向这个zval变量容器的变量(也称符号即symbol)个数
1.2 zval变量容器中有一个内部引用计数机制,来优化内存使用
1.3 把一个变量赋值给另一个变量将增加refcount次数,使用unset(),或是关联到某个变量容器的变量离开了作用域将减少一次refcount,变量容器在refcount为0时销毁。
<?php
$a = "new string";
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('a');
$c = $a;
xdebug_debug_zval('a');
unset( $b, $c );
xdebug_debug_zval('a');
$d = &$a;
xdebug_debug_zval('a');
?>
打印的结果应该为
a: (refcount=1, is_ref=0)='new string'
a: (refcount=2, is_ref=0)='new string'
a: (refcount=3, is_ref=0)='new string'
a: (refcount=1, is_ref=0)='new string'
a: (refcount=1, is_ref=1)='new string'
1.4 引用计算确保在引用不再需要时将内存返回给操作系统
1.5 符号表指向的每一个值都有一个引用计数
参考文献:
手册 http://www.php.net/manual/zh/features.gc.refcounting-basics.php
2 写时复制
2.1 写时复制确保在变量之间复制时不浪费内存
2.2 当一个变量复制到另一个变量时,php并没有因此而得到更多的内存,而是更新符号表,以表明这两个变量是同一块内存的名字,所以下面的代码实际上并没有生成一个新的数组
$worker = array(1,3,5,5);
$worker1 = $woker; // 数组并没有被复制
如果修改任意一个拷贝,那么php将分配内存并产生该拷贝。
$worker[1] = 36; //数组被复制,值发生变化
此时,worker和worker1的计数都为1
参考文献
http://www.cnblogs.com/codebean/archive/2011/05/27/2059888.html
二 zend_alloc中关于内存的管理
参见下图
1 php源码文件中的文件zend/zend_alloc.h的下载地址为
http://www.oschina.net/code/explore/php-5.2.15/Zend/zend_alloc.c
http://www.oschina.net/code/explore/php-5.2.15/Zend/zend_alloc.h
2 struck heap
2.1 是一种数据结构的定义,参见源码中struct _zend_mm_heap处
什么是heap
http://zhezhide.blog.163.com/blog/static/325233002011443271278/
_zend_mm_heap
名词解释:
1 内存 :http://baike.baidu.com/view/1082.htm
2 符号表:符号表示记录符号属性的表,它的每一表项表示一个标示符的属性信息。这些属性信息通常包括种类(常数,变量,数组,标号等),类型(整型,逻辑型,字符型等),给名字分配的存储单元地址等。用于编译器区分变量,常量,关键字(if,else等),数字,字符串等东西的一个链表。参见官方文档
待续