关于PHP的内存管理
时间:2009-06-11
来源:互联网
首先我们看看PHP在C中变量的形式:
typedef struct _zval_struct {
zvalue_value value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
refcount是引用计数器,is_ref是判断是否被引用了。要注意的是refcount和is_ref没有直接的关系的!看下面的例子:
<?php
$a = ‘Hello World’;
$b = $a;
?>
我们可以看到程序先创建一个$a变量, 然后赋值$a变量为’HelloWorld’.然后创建$b变量,把$a变量赋值给$b变量.在这里我们要思考的是,现在内存情况是怎样的.假如$a变量的内存占用为22字节(假设值)的话,那$b占用多少字节呢? 22字节? 还是小于22字节呢? 答案是小于22字节.那PHP是怎样实现的呢?
其实PHP是通过refcount来实现的.当一个变量赋值给另外一个变量的时候, PHP只是简单的把变量的refcount的值加1.使用的是zend_hash_add函数和ZVAL_ADDREF宏.详细可以参考以下代码:
{
zval*helloval;
MAKE_STD_ZVAL(helloval);
ZVAL_STRING(helloval,"HelloWorld",1);
zend_hash_add(EG(active_symbol_table),"a",sizeof("a"),&helloval,sizeof(zval*),NULL);
ZVAL_ADDREF(helloval);
zend_hash_add(EG(active_symbol_table),"b",sizeof("b"),&helloval,sizeof(zval*),NULL);
}
从上面的代码可以看到变量是没有增加的, 依然是helloval一个变量.但是我们还可以看到通过ZVAL_ADDREF宏来增加了引用计数器.所以helloval->refcount++.而且这时候还通过zend_hash_add向活动符号表增加了一个符号名称为b的符号.所以这样就可以把内存使用减到最少.
我们可以通过使用PHP的内置函数memory_get_usage()来验证一下.代码如下:
<?php
$m1 = memory_get_usage();
$a = 1;
$m2 = memory_get_usage();
$b = $a;
$m3 = memory_get_usage();
echo $m2 - $m1 , "<br />", $m3 - $m2;
?>
实验证明我们的说法是对的!
那么$b什么时候才可以变成真正的变量呢? 我们可以使用把$b赋值一个新的值:
<?php
$a = 1;
$b = $a;
$b = 2;
?>
这样就可以在内存里分配新的空间了!
今天就说到这里!下次再讲讲&的作用!
typedef struct _zval_struct {
zvalue_value value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
refcount是引用计数器,is_ref是判断是否被引用了。要注意的是refcount和is_ref没有直接的关系的!看下面的例子:
<?php
$a = ‘Hello World’;
$b = $a;
?>
我们可以看到程序先创建一个$a变量, 然后赋值$a变量为’HelloWorld’.然后创建$b变量,把$a变量赋值给$b变量.在这里我们要思考的是,现在内存情况是怎样的.假如$a变量的内存占用为22字节(假设值)的话,那$b占用多少字节呢? 22字节? 还是小于22字节呢? 答案是小于22字节.那PHP是怎样实现的呢?
其实PHP是通过refcount来实现的.当一个变量赋值给另外一个变量的时候, PHP只是简单的把变量的refcount的值加1.使用的是zend_hash_add函数和ZVAL_ADDREF宏.详细可以参考以下代码:
{
zval*helloval;
MAKE_STD_ZVAL(helloval);
ZVAL_STRING(helloval,"HelloWorld",1);
zend_hash_add(EG(active_symbol_table),"a",sizeof("a"),&helloval,sizeof(zval*),NULL);
ZVAL_ADDREF(helloval);
zend_hash_add(EG(active_symbol_table),"b",sizeof("b"),&helloval,sizeof(zval*),NULL);
}
从上面的代码可以看到变量是没有增加的, 依然是helloval一个变量.但是我们还可以看到通过ZVAL_ADDREF宏来增加了引用计数器.所以helloval->refcount++.而且这时候还通过zend_hash_add向活动符号表增加了一个符号名称为b的符号.所以这样就可以把内存使用减到最少.
我们可以通过使用PHP的内置函数memory_get_usage()来验证一下.代码如下:
<?php
$m1 = memory_get_usage();
$a = 1;
$m2 = memory_get_usage();
$b = $a;
$m3 = memory_get_usage();
echo $m2 - $m1 , "<br />", $m3 - $m2;
?>
实验证明我们的说法是对的!
那么$b什么时候才可以变成真正的变量呢? 我们可以使用把$b赋值一个新的值:
<?php
$a = 1;
$b = $a;
$b = 2;
?>
这样就可以在内存里分配新的空间了!
今天就说到这里!下次再讲讲&的作用!
作者: liexusong 发布时间: 2009-06-11
不错。
作者: 逆雪寒 发布时间: 2009-06-11
好像在laurance 的一篇文章中,有对
typedef struct _zval_struct {
zvalue_value value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
进行详细解释
对变量的赋值给予了解释
typedef struct _zval_struct {
zvalue_value value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
进行详细解释
对变量的赋值给予了解释
作者: chnzbq 发布时间: 2009-06-13
不错的说
作者: gently 发布时间: 2009-06-16
不错的东西
作者: Kevin-Lau 发布时间: 2009-11-17
真的不错
作者: mmxcq 发布时间: 2009-11-17
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28