PHP垃圾回收机制

引用计数基本知识###

每个php变量存在一个叫"zval"的变量容器中。一个zval变量容器,包括4个东西:变量的类型、变量的值、占用一个字节的bool值is_ref(标识是否是属于引用集合),占用一个字节的refcount(表示指向这个zval变量容器的变量个数)。

当一个变量被赋常量值时,就会生成一个zval变量容器,栗子:$a = "new string";在这里,生成了一个新的变量容器,类似是string,值是a,is_ref默认是false,因为没有任何自定义的引用生成,refcount是1,因为这里只有一个变量使用这个变量容器,并且当refcount=1时,is_ref用于是false。

把一个变量赋值给另一变量将增加引用次数(refcount),栗子:

$a = "new string";
$b = $a;

这时候$a容器变量的refcount=2,is_ref还是false,php不会复制已经生成的变量容器,当refcount=0时变量容器会自动销毁,任何关联到$a变量容器的变量执行unset时,refcount就会减一。

复合类型

考虑像array和object这样的复合类型,他们的变量是把他们的成员或属性保存在自己的符号表中,这意味着下面的栗子会生成3个zval变量容器: a,meaning和 number。

$a = array( 'meaning' => 'life', 'number' => 42 );


如果这个时候我们把$a已经存在的元素添加到$a中:

$a = array( 'meaning' => 'life', 'number' => 42 );
$a['life'] = $a['meaning'];


这时候$a[‘life’]的refcount就变成了2,实际上$a[‘meaning’]和$a[‘life’]指向的都是同一个变量容器。

把$a的引用作为一个元素添加到$a中:

$a = array( 'one' );$a[] =& $a;


$a的refcount变成了2,$a中的&$a指向的原始数组,这个时候如果unset($a),就会是这样:

这个时候已经没有任何作用域中的任何符号指向这个变量容器了,由于数组元素“1”仍然指向数组本身,所以这个容器不能被清除 。因为没有另外的符号指向它,所以没有办法清除这个结构,结果就会导致内存泄漏。庆幸的是,php将在脚本执行结束时清除这个数据结构,但是在php清除之前,将耗费不少内存。

php通过一个垃圾回收算法来处理这个内存泄漏的问题,这个算法就不在这里细说了,算法的基本规则:如果一个引用计数增加,它将继续被使用,当然就不再在垃圾中。如果引用计数减少到零,所在变量容器将被清除。就是说,仅仅在引用计数减少到非零值时,才会产生垃圾周期,php会把一些可能为垃圾的容器(可能根)放在一个根缓冲区中,当这个缓冲区满了就会执行垃圾回收操作。

默认的,PHP的垃圾回收机制是打开的, 可以通过php.ini 的zend.enable_gc 来设置。当垃圾回收机制打开时,每当根缓存区存满时,就会执行垃圾护手算法筛选出垃圾。根缓存区有固定的大小,可存10,000个可能根,可以通过修改PHP源码文件Zend/zend_gc.c中的常量GC_ROOT_BUFFER_MAX_ENTRIES,然后重新编译PHP,来修改这个10,000值。当垃圾回收机制关闭时,循环查找算法永不执行,然而,可能根将一直存在根缓冲区中,不管在配置中垃圾回收机制是否激活。

当垃圾回收机制关闭时,如果根缓冲区存满了可能根,更多的可能根显然不会被记录。那些没被记录的可能根,将不会被这个算法来分析处理。如果他们是循环引用周期的一部分,将永不能被清除进而导致内存泄漏。

即使在垃圾回收机制不可用时,可能根也被记录的原因是,相对于每次找到可能根后检查垃圾回收机制是否打开而言,记录可能根的操作更快。不过垃圾回收和分析机制本身要耗不少时间。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容