面试了10家公司,拿到了9份offer。2020PHP面试真题ps:本文包含精选面试题和知识文章。PHP面试题关于PHP的垃圾回收机制,PHP的垃圾回收机制引用计数(referencecounting)GC机制,PHP可以自动进行内存管理,清除不需要的对象,PHP面试题分享关于垃圾回收机制的PHP面试题:★我的php学习交流社区-856460874。群里的管理准备好了。BAT等一线厂商的进阶知识体系已经准备就绪(相关学习资料和笔试面试题)。欢迎一起升职=点击添加面试题介绍PHP的垃圾回收机制。PHP使用referencesCounting(引用计数)GC机制,同时使用rootbuffer机制,当PHP发现有循环引用的zval时,会把它放到rootbuffer中,当rootbuffer达到配置中指定的个数时文件,就会进行垃圾回收,解决循环引用导致的内存泄露问题。1、如果引用计数减为零,变量容器就会被清除(free),这不是垃圾;2、如果一个zval的引用计数在reduce后仍然大于0,就会进入垃圾循环。第二,在一次垃圾循环中,通过检查引用计数是否减1,检查哪些变量容器的引用计数为零,从而找出哪一部分是垃圾。每个对象都包含一个引用计数器refcount,每个引用都连接到该对象,计数器加1。当引用离开生存空间或设置为NULL时,计数器减1。当引用计数器的一个对象为零,PHP知道你将不再需要使用这个对象并释放它占用的内存空间。下列关于PHP垃圾回收的说法中哪项是错误的?A.开启/关闭垃圾回收机制可以通过修改php配置来实现。B、可以在程序中使用gc_enable()和gc_disable()来开启和关闭。C、PHP中的垃圾回收机制将大大提高系统性能。D.开启垃圾回收机制后,可以节省大量内存空间以防内存泄漏,但由于垃圾回收算法需要时间运行,所以开启垃圾回收算法会增加垃圾回收算法的执行时间脚本。参考答案:C答案解析:PHP中的垃圾回收机制只会增加循环回收算法实际运行时的时间消耗。但在普通(较小的)脚本中,根本不会对性能产生影响。关于PHP垃圾收集机制的说法是否错误?A.在垃圾循环中,通过检查引用计数是否减1,查看哪些变量容器的引用为零,找出哪一部分是垃圾。B.可以通过调用gc_enable()和gc_disable()函数开启和关闭垃圾回收机制C.通过清理无用变量节省内存D.php代码执行后会自动进行垃圾回收,所以有不需要手动进行垃圾回收参考答案:D答案分析:一段php代码可能需要执行很长时间,但是如果这期间有未引用的变量,会占用内存空间,导致运行缓慢等问题.知识点1.概念垃圾回收是一种内存管理机制,大多数编程语言中都有。与非托管语言:C、C++和ObjectiveC相反,需要用户手动收集内存,具有GC机制的语言:Java、javaScript和PHP可以自动管理内存。垃圾回收机制(garbagecollectionmechanism,简称gc),顾名思义就是垃圾的再利用,是一种动态的存储分配方案。它会自动释放程序不再需要的已分配内存块。垃圾回收机制让程序员不必太在意程序内存分配,从而可以将更多的精力投入到业务逻辑中。在目前流行的语言中,垃圾回收机制是新一代语言的共同特点,如Python、PHP、C#、Ruby等,都使用了垃圾回收机制。二、PHP垃圾回收机制1、在PHP5.3之前,使用的垃圾回收机制很简单就是“引用计数”。什么是引用计数?由于PHP是用C写的,所以在C中有一种叫做结构体的东西,我们的PHP变量在C中就是这样存储的。每个PHP变量都存在一个叫做zval的容器中,zval容器中除了包含变量名和值,还包括两个字节的附加信息:●?? 一个叫'is_ref',是一个布尔值,用来表示这个变量是否属于引用集,通过这个字节,我们可以区分普通变量和引用变量PHP。● 第二个多出来的字节是'refcount',用来表示指向这个容器的变量个数。即:①每个内存对象分配一个计数器,当内存对象被变量引用时,计数器+1;②当变量引用被移除时(执行unset()后),计数器为-1;③当计数器=0时,表示内存对象未被使用,内存对象被销毁,垃圾回收完成。而PHP会在一个生命周期结束后释放这个进程/线程所占用的内容。这种方式决定了PHP前期不需要过多考虑内存泄漏问题。但是当两个或多个对象相互引用形成环时,内存对象的计数器不会减为0;这时候这组内存对象就没有用了,而且不能回收,导致内存泄漏。从php5.3开始,使用了新的垃圾回收机制。基于引用计数,实现了一个复杂的算法来检测内存对象中引用环的存在,以避免内存泄漏。2、随着PHP的发展,PHP开发人员的增多及其业务范围的扩大,在PHP5.3中引入了更加完善的垃圾回收机制。新的垃圾回收机制解决了引用内存无法处理循环泄漏的问题。正如官方文档所说:每个php变量都存在于一个名为“zval”的变量容器中。一个zval变量容器,除了包含变量的类型和值外,还包含两个字节的附加信息。第一个是“is_ref”,它是一个bool值,用来标识这个变量是否属于一个引用集(referenceset)。通过这个字节,php引擎可以区分普通变量和引用变量。由于php允许用户通过使用&来自定义引用,所以在zval变量容器中也有一个内部引用计数机制来优化内存使用。第二个多出来的字节是“refcount”,用来表示指向这个zval变量容器的变量(也叫symbols或symbols)的个数。所有符号都存在于一个符号表中,每个符号表都有一个作用域。根据官方文档,您可以使用Xdebug检查引用计数:上面的例程会输出:a:(refcount=3,is_ref=0)='newstring'a:(refcount=1,is_ref=0)='newstring'注:来自从PHP7的NTS版本开始,不再统计上述例程的引用计数,即$c=$b=$a后a的引用计数也为1。具体分类如下:在PHP7,zval可以引用计数也可以不引用。zval结构中有一个标志决定了这一点。①对于null、bool、int、double类型的变量,refcount永远不会计数;②对于object和resource类型,refcount计数与php5一致;③对于字符串,未引用的变量称为“实际字符串”。并且那些被引用的字符串被去重(即只有一个插入的字符串具有特定内容)并保证在整个请求期间都存在,因此不需要对它们使用引用计数;如果使用opcache,这些字符串将存在于共享内存中,在这种情况下,你不能使用引用计数(因为我们的引用计数机制是非原子的);④对于数组,未被引用的变量称为“不可变数组”。数组本身的计数与php5是一致的,但是数组中每个键值对的计数遵循前面三个规则(即如果是字符串则不计数);如果使用opcache,代码中的常量数组文本将被转换为不可变数组。同样,它们位于共享内存中,因此无法使用重新计数。我们的demo示例如下:;$b=&$a;xdebug_debug_zval('a');echo'测试数组引用计数';$c=array('a','b');xdebug_debug_zval('c');$d=$c;xdebug_debug_zval('c');$c[2]='c';xdebug_debug_zval('c');echo'testinttypecount';$e=1;xdebug_debug_zval('e');看到输出如下:3.回收周期默认情况下,PHP的垃圾回收机制是开启的,php.ini中有一个设置可以修改:zend.enable_gc。开启垃圾回收机制后,算法会判断,每当根缓冲区满了,就会进行循环查找。rootbuffer有一个固定的大小,默认是10000,可以通过修改PHP源文件Zend/zend_gc.c中的常量GC_ROOT_BUFFER_MAX_ENTRIES,然后重新编译PHP来修改这个值。当禁用垃圾回收时,循环搜索算法永远不会被执行,然而,根将始终存在于根缓冲区中,无论是否在配置中启用垃圾回收。除了修改配置zend.enable_gc外,还可以分别调用gc_enable()和gc_disable()函数来开启和关闭php运行时的垃圾回收机制。调用这些函数与修改配置项开启或关闭垃圾回收机制效果相同。即使根缓冲区可能尚未满,也强制定期回收。您可以为此调用gc_collect_cycles()函数。此函数将返回使用此算法回收的循环数。允许打开和关闭垃圾收集并允许自主初始化的原因是因为应用程序的某些部分可能对时间敏感。在这种情况下,您可能不想使用垃圾回收。当然,关闭部分应用程序的垃圾收集可能会带来内存泄漏的风险,因为某些可能的根可能不适合有限的根缓冲区。因此,在调用gc_disable()释放内存之前调用gc_collect_cycles()可能是明智的。因为这会清除所有已经存储在根缓冲区中的可能根,然后当关闭垃圾收集时,可以留下一个空缓冲区,为可能的根留出更多空间。4.性能影响1.内存占用的节省首先,实现垃圾回收机制的全部原因是在满足前提条件的情况下,通过清理循环引用的变量来节省内存占用。在PHP执行中,一旦根缓冲区已满或调用gc_collect_cycles()函数时,就会执行垃圾收集。2.增加执行时间垃圾回收影响性能的第二个方面是释放泄漏内存所花费的时间。通常PHP中的垃圾回收机制只有在循环回收算法实际运行时才会有时间消耗的增加。但在普通(较小的)脚本中,根本不会对性能产生影响。3.在运行回收机制的正常脚本的情况下,内存节省将允许更多此类脚本同时在您的服务器上运行。因为使用的总内存还没有达到上限。这种好处在长时间运行的脚本中尤其明显,例如长时间的测试套件或守护程序脚本。同时,对于通常运行时间比Web脚本更长的脚本应用程序,新的垃圾回收机制应该会大大改变内存泄漏难以解决的看法。最后祝大家面试顺利,拿到心仪的offer。我整理了一些这方面的资料,包括但不限于:分布式架构、高扩展性、高性能、高并发、服务器性能调优、TP6、laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql优化、shellScripts、需要进阶干货的可以免费分享Docker、微服务、Nginx等知识点给大家。如果你想和一群3-8岁的资深开发者交流学习,你需要,我的官方群-点这里。腾讯T3-T4标准精品PHP架构师教程目录大全,只要你看了,你的薪水更上一层楼(持续更新中)!
