代码改变世界

php内存管理

2012-10-31 00:26  phpor  阅读(489)  评论(0编辑  收藏  举报

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

http://zhidao.baidu.com/question/55324751.html&bdtkn=6eaa5b13712f962f4408a37fa3ae24b08a119ef88078338d51fed8133ea5c69d362ad36bb4bcda3b39bb3949f6bbe47087ac3af56e60b1f4e7eb60157d59fe309960acf940491fc7006f430fdc33b10a3975e807785db88bd4393674722a4620cd610b363ab2adace909eabbc9da880bc23122ff4

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等),数字,字符串等东西的一个链表。参见官方文档

 

 

待续