每一种计算机语言都有自己的自动垃圾回收机制,让程序员不必过分关心程序内存分配,php也不例外,但是在面向对象编程(OOP)编程中,有些对象需要显式的销毁,防止程序执行内存溢出。

一、PHP 垃圾回收机制(Garbage Collector 简称GC)

在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾。PHP会将其在内存中销毁;这是PHP的GC垃圾处理机制,防止内存溢出。当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中所有对象同时被销毁。GC进程一般都跟着每起一个SESSION而开始运行的。gc目的是为了在session文件过期以后自动销毁删除这些文件。

二、__destruct /unset

__destruct() 析构函数,是在垃圾对象被回收时执行。unset 销毁的是指向对象的变量,而不是这个对象。

三、 Session 与 GC

由于PHP的工作机制,它并没有一个daemon线程来定期的扫描Session信息并判断其是否失效,当一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor的值,来决定是否启用一个GC, 在默认情况下,session.gc_probability=1, session.gc_divisor =100也就是说有1%的可能性启动GC(也就是说100个请求中只有一个gc会伴随100个中的某个请求而启动)。

GC的工作就是扫描所有的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,如果生存时间超过gc_maxlifetime(默认24分钟),就将该session删除。但是,如果你Web服务器有多个站点,多个站点时,GC处理session可能会出现意想不到的结果,原因就是:GC在工作时,并不会区分不同站点的session。

那么这个时候怎么解决呢?

修改session.save_path,或使用session_save_path()让每个站点的session保存到一个专用目录。

提供GC的启动率,自然,GC的启动率提高,系统的性能也会相应减低,不推荐。

在代码中判断当前session的生存时间,利用session_destroy()删除。

看下面的例子:

Example 1: gc.php

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

echo $b ."n";

?>

不用说 % php -f gc.php 输出结果非常明了:

hy0kl% php -f gc.php

I am test.

好,下一个:

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

$b = 'I will change?';

echo $a ."n";

echo $b ."n";

?>

执行结果依然很明显:

hy0kl% php -f gc.php

I will change?

I will change?

君请看:

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

unset($a);

echo $a ."n";

echo $b ."n";

?>

是不是得想一下下呢?

hy0kl% php -f gc.php

Notice: Undefined variable: a in /usr/local/www/apache22/data/test/gc.php on line 8

I am test.

君再看:

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

unset($b);

echo $a ."n";

echo $b ."n";

?>

其实如果 Example 3 理解了,这个与之异曲同工。

hy0kl% php -f gc.php

I am test.

Notice: Undefined variable: b in /usr/local/www/apache22/data/test/gc.php on line 9

君且看:

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

$a = null;

echo '$a = '. $a ."n";

echo '$b = '. $b ."n";

?>

猛的第一感觉是什么样的?

hy0kl% php -f gc.php

$a =

$b =

没错,这就是输出结果,对 PHP GC 已有深入理解的 phper 不会觉得有什么奇怪,说实话,当我第一次运行这段代码时很意外,却让我对 PHP GC 有更深刻的理解了。那么下面与之同工的例子自然好理解了。

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

$b = null;

echo '$a = '. $a ."n";

echo '$b = '. $b ."n";

?>

下面我们来详细分析 GC 与引用:

所有例子中,创建了一个变量,这个过程通俗一点讲:是在内存中开辟了一块空间,在里面存放了一个字符串 I am test。 。 PHP 内部有个符号表,用来记录各块内存引用计数,那么此时会将这块内存的引用计数 加 1,并且用一个名为 $a 的标签(变量)指向这块内存,方便依标签名来操作内存。

对变量 $a 进行 & 操作,我的理解是找到 $a 所指向的内存,并为 $b 建立同样的一引用指向,并将存放字符串 I am test。 的内存块在符号表中引用计数 加 1。换言之,我们的脚本执行到这一行的时候,存放字符串 I am test。 的那块内存被引用了两次。这里要强调的是, & 操作是建立了引用指向,而不是指针, PHP 没有指针的概念!同时有人提出说类似于 UNIX 的文件软链接。可以在一定程度上这么理解: 存放字符 I am test。 的那块内存是我们的一个真实的文件,而变量 $a 与 $b 是针对真实文件建立的软链接,但它们指向的是同一个真实文件。 So, 我们看到,在 Example 2 中给 $b 赋值的同时, $a 的值也跟着变化了。与通过某一软链操作了文件类似。

在 Example 3 与 4 中,进行了 unset() 操作。根据实际的执行结果,可以看出: unset() 只是断开这个变量对它原先指向的内存的引用,使变量本身成为没有定义过空引用,所在调用时发出了 Notice ,并且使那块内存在符号表中引用计数 减 1,并没有影响到其他指向这块内存的变量。换言之,只有当一块内存在符号表中的引用计数为 0 时, PHP 引擎才会将这块内存回收。

看看下面的代码与其结果:

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

unset($a);

unset($a);

unset($a);

echo '$a = '. $a ."n";

echo '$b = '. $b ."n";

?>

输出:

hy0kl% php -f gc.php

Notice: Undefined variable: a in /usr/local/www/apache22/data/test/gc.php on line 10

$a =

$b = I am test.

第一次 unset() 的操作已经断开了指向,所以后继的操作不会对符号表的任何内存的引用记数造成影响了。

赋值 null操作是相当猛的,它会直接将变量所指向的内存在符号号中的引用计数置 0,那这块内存自然被引擎回收了,至于何时被再次利用不得而知,有可能马上被用作存储别的信息,也许再也没有使用过。但是无论如何,原来所有指向那块内存变量都将无法再操作被回收的内存了,任何试图调用它的变量都将返回 null。

error_reporting(E_ALL);

$a = 'I am test.';

$b = & $a;

$b = null;

echo '$a = '. $a ."n";

echo '$b = '. $b ."n";

if (null === $a)

{

echo '$a is null.';

} else

{

echo 'The type of $a is unknown.';

}

?>

输出:

hy0kl% php -f gc.php

$a =

$b =

$a is null.

综上所述,充分说明了为什么我们在看开源产品源码的时候,常看到一些比较大的临时变量,或使用完不再调用的重用信息都会被集中或显示的赋值为 null 了。它相当于 UNIX 中直接将真实文件干掉了,所有指向它的软链接自然成了空链了。

之前在讨论到这些细节点时有很多想当然的念头,在实际的执行了测试代码后才发现: 哦,原来如此!纸上得来终觉浅,绝知此事须躬行。

php7垃圾回收机制l_从几个简单的程序看PHP的垃圾回收机制相关推荐

  1. java垃圾回收system_java应用性能调优之详解System的gc垃圾回收方法

    1.什么是System.gc()? System.gc()是用Java,C#和许多其余流行的高级编程语言提供的API.当它被调用时,它将尽最大努力从内存中清除垃圾(即未被引用的对象).名词解释:GC, ...

  2. Java程序员的日常—— 垃圾回收中引用类型的作用

    在Java里面,是不需要太过于关乎垃圾回收,但是这并不意味着开发者可以不了解垃圾回收的机制,况且在java中内存泄露也是家常便饭的事情.因此了解垃圾回收的相关知识就显得很重要了. 引用,在垃圾回收中是 ...

  3. 垃圾回收只知道标记清除?一文帮你打通V8垃圾回收

    前言 本文旨在帮你建议起垃圾回收的体系化知识,仔细品味目录,相信你能体会得的到. V8 垃圾回收核心思路 第一步 通过 GC Root 标记活动对象与非活动对象 如何判断活动对象? V8 通过 可访问 ...

  4. 垃圾回收器之串行、吞吐量优先、响应时间优先的的垃圾回收器

    4. 垃圾回收器 本篇讲述了串行.吞吐量优先.响应时间优先的垃圾回收器,关于自从JDK9 开始默认的 G1 垃圾回收器会在下篇文章讲述. 串行 单线程 堆内存较小,适合个人电脑 吞吐量优先 多线程 堆 ...

  5. java垃圾回收菜鸟_java程序员不懂JVM内存回收,两年后也是个菜鸟

    java程序员不懂JVM内存回收,两年后也是个菜鸟 在学java程序员的时候,如果你还不懂JVM内存回收,那么你就只能是个很一般的程序员菜鸟了,那么什么是JVM内存回收呢?今天我们就来学习,都还不深入 ...

  6. java什么算垃圾代码,[把代码写成诗]Java美好的承诺,自动回收垃圾

    导语 Java和C++有一堵内存分配的墙,墙内的人想进去,墙里的人想出去.C++程序员苦于内存泄漏,Java程序员羡慕C++程序员可以自己控制一切.Java语言向程序员做了一个美好的承诺,程序员不需要 ...

  7. 垃圾分类毕设java程序_北京垃圾分类首日:垃圾怎么分不用手抄,有个小程序助识别...

    (健康时报记者 林敬 董颖钰)5月1日,新修订的<北京市生活垃圾管理条例>开始实施.面对这个举措,家住北京通州区的王女士有点着急了,她告诉健康时报记者,主要的困惑是不知道怎么给垃圾进行分类 ...

  8. 思科sp ccie 认证中必看网络安全之垃圾邮件过滤技术

    思科sp ccie 认证中必看网络安全之垃圾邮件过滤技术,电子邮件是-种用电子手段提供信息交换的通信方式,是互联网应用最多的服务.通过网络的电子邮件系统,用户可以以非常低廉的价格.非常快速的方式,与世 ...

  9. 一个优秀的Java程序员必须了解的GC机制

    一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能提高整个应用程序 ...

  10. 一个简单的例子看java线程机制

    一个简单的例子看java线程机制 作者: zyf0808 发表日期: 2006-03-26 11:20 文章属性: 原创 复制链接 import java.util.*; public class T ...

最新文章

  1. cheat engine lua
  2. SAP Retail for SAP (non-Retail) Experts
  3. bat输出log日志操作
  4. 10个最佳Node.js企业应用案例:从Uber到LinkedIn
  5. nyoj-999 师傅又被妖怪抓走了
  6. docker run命令详解
  7. PostgreSQL和MySQL技术全面剖析
  8. Testing Round #16 (Unrated) C. Skier(map的应用)
  9. JavaScript常用DOM操作方法和函数
  10. 使用Jenkins搭建持续集成环境的方法(一)
  11. 给Visual Studio 2005设置一个代码边界线
  12. 物联网通信技术 机械工业 课后习题总结
  13. 2.Hadoop_入门_模板机IP地址和主机名称配置
  14. 【折腾服务器 1】妖板 Intel N5105 + i226 主板安装 ESXi 7.0 教程
  15. php工具能自动出代码的,打造自己的PHP半自动化代码审计工具
  16. 字体反爬之猫眼票房爬虫python
  17. 中控打卡机二次开发注册控件问题
  18. App前端,Web前端,后端,微信小程序到底该学啥?
  19. 我国现行的计算机软件保护条例是在,等三条例将施行
  20. 计算机应用基础1010转换为10进制,大学计算机应用基础期末考试试题及答案

热门文章

  1. IDE, virtio, virtio-scsi 硬盘区别
  2. 【英语:基础高阶_全场景覆盖表达】K3.口语陈述的思维拓展
  3. 【前端工程化】搭建vue-cli + cesium项目的脚手架及常见问题
  4. 一键清理系统垃圾文件,让你的电脑运行如飞,隐私也更安全!
  5. 带你重新认识一下应用层协议
  6. 表单验证:名称、电话号码、邮箱
  7. IOS实现SpotLight搜索 让你的APP支持SpotLight搜索
  8. 安卓和ios针对小程序兼容以及小程序技术实现上本身遇到的一些问题
  9. 天刃_张志刚_SEO优化技巧
  10. Python实战 | 送亲戚,送长辈,“ 月饼 ”可视化大屏来帮忙。