PHP-如何更好的利用php垃圾回收机制

PHP-如何更好的利用php垃圾回收机制

夜无邪 发布于 2017-05-05 字数 754 浏览 923 回复 2

我们平时写一个php脚本,一般都不用考虑内存泄露和垃圾回收的问题,因为一般情况下你的脚本很快就执行完退出了。

但在一些运行时间长,数据量大的时候,程序运行一段时间后,php脚本就占用了过多内存,然后就报错(PHP Fatal error: Allowed memory size of 134217728 bytes exhausted)退出了。一般来说,每个页面处理结束,新建的simple_html_dom对象就应该被销毁了——但是实际上没有,很明显,内存泄露发生了。

我在想我们怎么能写一个协助程序来协助php管理内存,比如利用unset,但是这个是相当于进入队列,并没有及时执行

比如:$a=new A(); unset($a);//并不会将$a的引用计数减到0;
还有就是利用$a = null 来直接将$a 指向的数据结构置空,同时将其引用计数归0。

但是都是我的一个模糊设想,我想大家给提供一个比较全面的处理机制,最好有实用性的代码配合!

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

虐人心 2017-05-23 2 楼

我之前看源码发现 php在声明数组变量时申请的是一大块空间
比如 a = array(); 而 unset(a);并不能把这个空间给释放掉, 必须手动将 a 赋一个 null值,它才会去释放这个空间

瑾兮 2017-05-22 1 楼

php5.3之前使用的垃圾回收机制是“引用计数”。

“引用计数”的原理也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器+1;当变量引用撤掉后,计数器-1;当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成。

“引用计数”存在问题,就是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0;这时会导致内存泄露。

现在我们来看看几个跟PHP内存释放有关的操作:

1、&符号的影响
显式引用一个变量,会增加该内存的引用计数:
$a = "something";
$b = &$a;

此时unset($a), 但是仍有$b指向该内存区域的引用,内存不会释放。

2、unset函数的影响
unset只是断开一个变量到一块内存区域的连接,同时将该内存区域的引用计数-1;但是在循环体内部,例如:$a=new A(); unset($a);并不会将$a的引用计数减到零;

3、对变量赋null值操作的影响;
$a = null 是直接将$a 指向的数据结构置空,同时将其引用计数归0。

4、脚本执行结束的影响
脚本执行结束,该脚本中使用的所有内存都会被释放,不论是否有引用环。

那么以上介绍了这么多和内存有关的东西,但是内存的回收都是由PHP的垃圾回收进程来进行的。当然你也可以像写C一样,自己手动回收进程,对所使用的变量进行null赋值。但这样会增加了程序的复杂度,而一般对于PHP来说不建议这样做,如果像你的问答里说的,在处理大量和运行时间长的代码里,那最好还是手动去销毁一些不使用的变量。并且可以通过memory_get_usage和memory_get_peak_usage等函数监测内存的使用情况。