php是世界上最好的语言?
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnTwwIjvqKrkejoLR3nianxD34G0x6J9NxRL3GpqAyzyjt9aplmkQ7tRQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这是我的第 </span><span style="color: black;">69</span><span style="color: black;"> 篇原创<span style="color: black;">文案</span></span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">作者 | 悟空聊架构</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">源自</span> | <span style="color: black;">悟空聊架构</span>(ID:PassJava666)</span></p><span style="color: black;">转载请联系授权(<span style="color: black;">微X</span>ID:PassJava)</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">艾小仙<span style="color: black;">近期</span>问我:PHP 是不是最好的语言?,我说论 <strong style="color: blue;">垃圾回收</strong>,PHP 可能更简单粗暴一点。艾小仙满脸惊疑:PHP 还有垃圾回收?</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Java 中的垃圾回收机制,<span style="color: black;">大众</span>肯定都有所<span style="color: black;">认识</span>,<span style="color: black;">例如</span><span style="color: black;">怎样</span>确定垃圾,有两种算法,引用计数法和<span style="color: black;">达到</span>性分析算法。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">Java 中<span style="color: black;">运用</span>的是<span style="color: black;">达到</span>性分析算法,而 PHP <span style="color: black;">运用</span>的引用计数算法。</p><span style="color: black;">咱们</span>都<span style="color: black;">晓得</span>引用计数算法较难处理<strong style="color: blue;">循环引用</strong>的问题,<span style="color: black;">PHP 这波奇怪的操作可太秀了</span>,那 PHP 的垃圾回收原理是怎么样的?
<h1 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">1、</span>PHP 中的引用计数</span></h1>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">1.1 <span style="color: black;">怎样</span>确定垃圾</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">原理:</span> 给对象添加一个引用计数器,每当有一个<span style="color: black;">地区</span>引用它,计数器的值就加一。每当有一个引用失效,计数器的值就减一。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>一个变量 value 的 refcount 减一之后等于 0,此 value <span style="color: black;">能够</span>被释放掉,不属于垃圾。<span style="color: black;">垃圾回收器不会处理</span> 。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倘若</span>一个变量 value 的 refcount 减一之后还是大于 0,此 value 被认为<span style="color: black;">不可</span>被释放掉,可能<span style="color: black;">作为</span>一个垃圾。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">垃圾回收器将可能的垃圾收集起来,等达到<span style="color: black;">必定</span>数量后<span style="color: black;">起始</span><span style="color: black;">起步</span>垃圾鉴定程序,把真正的垃圾释放掉。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">缺点:</span> 需要<span style="color: black;">守护</span>引用计数器,有<span style="color: black;">必定</span>的消耗。且较难处理循环引用的问题。后面<span style="color: black;">亦</span>会讲到<span style="color: black;">怎样</span><span style="color: black;">处理</span>这个问题。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">下面的例子说明引用计数的是<span style="color: black;">怎样</span>变化的:</p><span style="color: black;">//这个 value 被变量$x 引用 1 次,refcount = 1</span>$x = <span style="color: black;">array</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(); </p><span style="color: black;">//这个 value 被变量$x,$y 分别引用 1 次,refcount = 2</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">$y = $x;</p><span style="color: black;">//这个 value 被变量 $x, $y, $z 分别引用 1 次,refcount = 3</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">$z = $y;</p><span style="color: black;">//这个 value 被变量$x,$z 分别引用 1 次,refcount = 2,</span><span style="color: black;">//$y 被销毁了,<span style="color: black;">无</span>引用 array 这个 value</span><span style="color: black;">unset</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">($y); </p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">1.2 PHP 中的变量知识</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">每一个</span> php 变量存在一个叫 zval 的变量容器中。一个 zval 变量容器,除了<span style="color: black;">包括</span>变量的类型和值,还<span style="color: black;">包含</span>两个字节的额外信息。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">第1</span>个是 is_ref,是个 bool 值,用来标识这个变量<span style="color: black;">是不是</span>是属于引用集合(reference set) 。<span style="color: black;">经过</span>这个字节,php 引擎<span style="color: black;">才可</span>把普通变量和引用变量区<span style="color: black;">掰开</span>来,<span style="color: black;">因为</span> php <span style="color: black;">准许</span>用户<span style="color: black;">经过</span><span style="color: black;">运用</span>&来<span style="color: black;">运用</span>自定义引用,zval 变量容器中还有一个内部引用计数机制,来优化内存<span style="color: black;">运用</span>。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">第二个额外字节是 refcount,用以<span style="color: black;">暗示</span>指向这个 zval 变量容器的变量(<span style="color: black;">亦</span><span style="color: black;">叫作</span>符号即 symbol )个数。</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">1.3 <span style="color: black;">运用</span>引用计数的类型</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">有 5 种类型用的引用计数:</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">string、array、object、resource、reference</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">下面的表格说明了<span style="color: black;">仅有</span> type_flag 为以下 8 种类型且 IS_TYPE_REFCOUNTED=true 的变量才<span style="color: black;">运用</span>引用计数,如下表所示</p><img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnxCwpPQpJTYib9kveyricHAmryZAIsPtRI2wLUnL8x7xQPwx8KnujTWDg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"><span style="color: black;">运用</span>引用计数的类型<h1 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">2、</span>回收原理</span></h1>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">2.1. 回收<span style="color: black;">机会</span></span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">自动回收:在变量 zval 断开 value 的指向时,<span style="color: black;">倘若</span><span style="color: black;">发掘</span> refcount=0 则会直接释放 value。</p><span style="color: black;">断开 value 指向的情形:</span>(1)修改变量时会断开原有 value 的指向。(2)函数返回时会释放所有的局部变量。<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">主动回收</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">调用 unset() 函数。类似于 Java 中的 System.gc()</p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">2.2 垃圾鉴定</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">垃圾收集器收集的可能垃圾到达<span style="color: black;">必定</span>数量后,<span style="color: black;">起步</span>垃圾鉴定、回收程序。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;">原理:</strong>垃圾是<span style="color: black;">因为</span>成员引用<span style="color: black;">自己</span><span style="color: black;">引起</span>的,<span style="color: black;">那样</span>就对 value 的 refcount 减一操作,<span style="color: black;">倘若</span> value 的 refount 变为了 0,则<span style="color: black;">显示</span>其引用<span style="color: black;">所有</span>来自<span style="color: black;">自己</span>成员,value 属于垃圾。<img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnKhFoa6CYmo9Fn6FFiajR4lKUiacR5uZmQzKzQHtw0sZ86mmZTnjIgm4w/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;"><span style="color: black;">过程</span>一:</span> 遍历垃圾回收器的 buffer 缓冲区,把 value 标为灰色,把 value 的成员的 refount-1,标为白色。<span style="color: black;"><span style="color: black;">过程</span>二:</span>遍历垃圾回收器的 buffer 缓冲区,<span style="color: black;">倘若</span> value 的 refcount 等于 0,则认为是垃圾;<span style="color: black;">倘若</span>不等于 0,则<span style="color: black;">暗示</span>还有<span style="color: black;">外边</span>的引用,不是垃圾,将 refcount+1 还原回去,标为黑色。<span style="color: black;"><span style="color: black;">过程</span>三:</span> 遍历垃圾回收器的 buffer 缓冲区,将 value 为非白色的节点从 buffer 中删除,<span style="color: black;">最后</span> buffer 缓冲区中都是真正的垃圾。<span style="color: black;"><span style="color: black;">过程</span>四:</span> 遍历垃圾回收器的 buffer 缓冲区,释放此 value。<h1 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">3、</span>带你看源码</span></h1>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">1. 垃圾管家</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">我<span style="color: black;">叫作</span> _zend_gc_globals <span style="color: black;">结构体</span>为垃圾管家,它会对垃圾进行管理,收集到的可能<span style="color: black;">作为</span>垃圾的 value 就<span style="color: black;">保留</span>在这个结构的 buf 中,<span style="color: black;">叫作</span>为垃圾缓存区。<img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnMCRZYImeGictJwxtgbqVWZBqbgN2iaHGHuzIDweLtf7uPfV8icpls8MVw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">2. 垃圾管家初始化</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(1)php.ini 解析后调用 gc_init() 初始垃圾管家_zend_gc_globals。</p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">重点</span><span style="color: black;">功效</span><span style="color: black;">便是</span>分配缓冲区 buffer 空间和初始化配置。</p><img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnEeP6W7uCPXbHghJpzbG5ibWDJ8ShswzXicDibicS2Lq5Ik1a72BAOdU6Tw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">(2)gc_init() 函数里面调用 gc_reset() 函数初始化。
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">重点</span><span style="color: black;">功效</span><span style="color: black;">便是</span>初始化后续要用到的变量配置。</p><img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnVJyiaFibhLWcaKrTC6bl4XicIcBLdqxa3Xlk6iakXBZheGZBiaXGNHWgn9A/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">
<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">3. 判断<span style="color: black;">是不是</span>需要收集</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">(1)在销毁一个变量时就会判断<span style="color: black;">是不是</span>需要收集。调用 i_zval_ptr_dtor() 函数<img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dn6fXb69mf3p6vcwI5qz9QBWr6UHHqF8869xMFiaMVfhia0awZF4jWnLFw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">倘若</span> refcount 减一后,<strong style="color: blue;">refcount 等于 0</strong>,则认为不是垃圾,调用 _zval_dtor_func <span style="color: black;">办法</span>释放此 value。<span style="color: black;">倘若</span> refcount 减一后,<strong style="color: blue;">refcount 大于 0</strong>,则认为 value <strong style="color: blue;">可能</strong>是垃圾,垃圾管家进行收集。<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">4. 收集垃圾</span></h2><img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dn1Rmm1EkHUTQxjWgkypia1zCMPY9Qgp6tqwljrFWI51Zy4haFJtGCLuQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">gc_possible_root<span style="color: black;">办法</span>拿出 unused 指向的节点。<span style="color: black;">倘若</span>拿出的节点是可用的,则将 unused 指向下一个节点。<span style="color: black;">倘若</span> unused <span style="color: black;">无</span>可用的,且 first_unused 还<span style="color: black;">无</span>推进到 last_unused,则<span style="color: black;">暗示</span> buf 缓存区中还有可用的节点。拿出 first_unused 指向的节点。first_unused 指向下一个节点。buf 缓存区已满,<span style="color: black;">起步</span>垃圾鉴定、垃圾回收。<span style="color: black;">倘若</span>未启用垃圾回收,则直接返回。<img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dn7dbEBticj6qoDODLo4Tiazdghf1u2YcXrSw7ibu3BbuTJpmPgCwE7xWwA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;">将<span style="color: black;">插进</span>的变量标为紫色,防止重复<span style="color: black;">插进</span>。将该节点在 buf 数组中的位置<span style="color: black;">保留</span>到了 gc_info 中,当后续 value 的 refcount 变为了 0。需要将其从 buf 中删除时<span style="color: black;">能够</span><span style="color: black;">晓得</span>该 value <span style="color: black;">保留</span>在哪个 gc_root_buffer 中。<h2 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">5. 释放垃圾</span></h2>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">因为</span>回收<span style="color: black;">办法</span> zend_gc_collect_cycles() 实在是太长,我把几个关键<span style="color: black;">过程</span>理出来了:<img src="https://mmbiz.qpic.cn/mmbiz_png/SfAHMuUxqJ2Pom2SWe5RN8mtwiazSm7dnZoXYJWMMqVAB9Lk3tVYn7jYRuysUHcm7Y5AqnUQ8wcVsE5hjmK8OfA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>扫描根节点收集根节点调用回收器清理变量收集完成<h1 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;"><span style="color: black;">4、</span>总结</span></h1>PHP 的垃圾回收和 Java 的垃圾回收还是<span style="color: black;">特别有</span>很大区别的,<span style="color: black;">咱们</span>都以为<span style="color: black;">无</span>高级语言会用到引用计数法来回收垃圾,但偏偏 PHP 用的是引用计数。PHP 用了一套自己的算法来<span style="color: black;">处理</span>因循环引用而产生垃圾的问题,这套算法<span style="color: black;">能够</span>简单理解为先把可疑垃圾的引用计数减一来进行测试,<span style="color: black;">倘若</span>引用计数确实等于 0 ,则标记颜色为黑色,后续<span style="color: black;">一块</span>清理。PHP 垃圾收集中总共用到了三种关键颜色:白色- 垃圾,黑色- 非垃圾,紫色- 防止重复<span style="color: black;">插进</span>。<strong style="color: blue;">那PHP 到底是不是最好的语言?欢迎留言区讨论!</strong>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">- END -</span></p>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">建了学习交流群,<span style="color: black;">能够</span>扫码加我,备注<strong style="color: blue;">[加群]</strong> <span style="color: black;">一块</span>进阶!</p>
<h3 style="color: black; text-align: left; margin-bottom: 10px;"><span style="color: black;">个人二维码</span></h3>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/SfAHMuUxqJ0iaLH3DMqPJPOgsSJNhx9RkQs3eSZkpqFWGicORO7gicxM38tIYUTP6mNqS1oFrYOxsA9tjA2DVrqibg/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">“</span>
<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">我是悟空,7 年一线互联网<span style="color: black;">研发</span>经验,全栈一枚,现任<span style="color: black;">研发</span>组长。手写了一套 Spring Cloud 实战教程和 PMP 刷题小程序,在<span style="color: black;">机构</span>被誉为「工具小王子」。关注<span style="color: black;">就可</span>免费订阅教程和刷题。</p><span style="color: black;">”</span><strong style="color: blue;"><span style="color: black;"><span style="color: black;">我是悟空,<span style="color: black;">奋斗</span>变强,变身超级赛亚人!</span></span></strong>
对于这个问题,我有不同的看法... 外贸网站建设方法 http://www.fok120.com/ 谷歌外贸网站优化技术。
页:
[1]