PHP 垃圾回收机制收集

1.应用场景

了解学习PHP[内存]垃圾回收机制, 帮助理解编程语言的运行机制, 提高开发水平.

2.操作/学习

PHP进行内存管理的核心算法一共两项:一是引用计数,二是写时拷贝,请(please)理(bei)解(song)

 

1.引用计数

使用的是“引用计数”方式进行回收。
简单地理解的话,就是每个分配的内存区域都有一个计数器,记录有多少个变量指针指向这片内存。当指向该片内存的指针数量为0,那么该片内存区域就可以被回收。
引用计数计数简单,强大,但是有一个致命的缺陷,就是环状引用。
code:
$a = []; 
$a[] = &$a; 
unset($a); 


变量$a引用了自己,形成一个环。$a被unset,但由于存在环状引用,因此$a之前指向的内存的引用计数为1,因此该内存区域不会被垃圾回收机制回收。
 
PHP5.3针对这个重大的缺陷做了优化。虽然其基础仍然是引用计数,但是在做了一些改良,能够将环状引用导致的内存泄露控制在一定的规模以内。
当然,这并不是说你可以随便滥用内存,编写代码时仍然要小心为上!//this is the key point!!
 
其他要点:
1.PHP脚本运行完毕,该脚本申请的所有内存空间都会释放,不管是否存在环状引用。因此环状引用内存泄露的问题一般只影响长时间运行的程序脚本。 
2.垃圾回收机制需要满足一定的条件才会执行。因此unset后,系统并不一定会立即回收垃圾。
3.unset的作用。
“unset只是断开一个变量到一块内存区域的连接,同时将该内存区域的引用计数-1”。也就是说,如果有一个以上的变量指向同一个内存区域,或者存在环状引用,那么unset不会使内存区域释放。断开也说明unset并不会直接删除内存区域,而只是改变其引用计数而已。
4.$xx=null的作用。
“$a = null 是直接将$a 指向的数据结构置空,同时将其引用计数归0”。根据我对这个定义的理解,=null操作可以立即释放掉内存空间!因此很多PHP技巧中不厌其烦地对我们说,先将变量设为null,再unset。理解其深层原理后,我才彻底理解了这样做的原因!=null才是王道!

2.写时拷贝

即:变量的普通赋值与引用赋值

两者的区别:

https://blog.csdn.net/william_n/article/details/93601962

 

// 先不要问为什么非要加mt_rand,不然,绝笔说不过来了,到处都是坑
$a = 'hello'.mt_rand( 1, 1000 );
$b = $a;
$a = 123;
echo $b.PHP_EOL;
// 运行结果,不用我说吧,脚趾头都知道是'hello'.mt_rand( 1, 1000 )的结果,绝对不可能是123。

其实,当你把$a赋值给$b的时候,$a的值并没有真的复制了一份,这样是对内存的极度不尊重,也是对时间复杂度的极度不尊重,计算机仅仅是将$b指向了$a的值而已,这就叫多快好省。
那么,什么时候真正的发生复制呢?就是当我们修改$a的值为123的时候,这个时候就不得已进行复制,避免$b的值和$a的一样。

 

 

Q: 什么样的情况会导致zend_value的refcount不为0,但是这个zend_value却是个垃圾呢?

A: PHP7种两种情况:

  1. 数组:数组的某个成员使用&引用自己

  2. 对象:对象的某个成员引用对象自己

    请理(bei)解(song),一般面试,你能回答到这一步,已经非常屌了!

3. 垃圾回收函数  //使用哪些函数可以进行垃圾回收

TBD

4.资源参考:

https://www.cnblogs.com/wangzhaobo/articles/9591551.html   //PHP的垃圾回收机制以及大概实现  写得不错!

https://www.cnblogs.com/zhangyuhang3/p/6873619.html   //PHP垃圾回收机制理解  //也不错

后续补充

... 

你可能感兴趣的:(后端-BACK,END,PHP)