php 垃圾回收

php 垃圾回收

来源: http://php.net/manual/zh/features.gc.refcounting-basics.php

<?php
$a = "new string";
$b = $a;
xdebug_debug_zval( ‘a‘ );
?>

a: (refcount=2, is_ref=0)=‘new string‘

当任何关联到某个变量容器的变量离开它的作用域 (比如: 函数执行结束), 或者对变量调用了函数 unset()时, refcount 就会减 1
普通的引用计数法会把引用为 0 的 马上清除 (不清楚是多久, 反正很快), 浪费时间

来源: http://php.net/manual/en/features.gc.collecting-cycles.php

为避免不得不检查所有引用计数可能减少的垃圾周期, 引用计数浪费时间

To avoid having to call the checking of garbage cycles with every possible decrease of a refcount, the algorithm instead puts all possible roots (zvals) in the "root buffer" (marking them "purple"). It also makes sure that each possible garbage root ends up in the buffer only once. Only when the root buffer is full does the collection mechanism start for all the different zvals inside. See step A in the figure above.

当根缓冲区满了之后, 检查所有的 引用根节点, 标记为紫色, 每个节点标记一次

In step B, the algorithm runs a depth-first search on all possible roots to decrease by one the refcounts of each zval it finds, making sure not to decrease a refcount on the same zval twice (by marking them as "grey").

让每个节点的引用减一, 通过把访问过的节点设置为灰色, 来确保不会删除同一个根节点两次 深度优先搜索

In step C, the algorithm again runs a depth-first search from each root node, to check the refcount of each zval again. If it finds that the refcount is zero, the zval is marked "white" (blue in the figure). If it‘s larger than zero, it reverts the decreasing of the refcount by one with a depth-first search from that point on, and they are marked "black" again.

如果引用是 0, 蓝色 (表示不可达), 表示要被垃圾回收器删除. (小于 0 也行吧, 有可能本身就是 0, 执行减一之后变成-1)
如果引用大于 0, 那些灰色的点, 让他们的引用加 1

In the last step (D), the algorithm walks over the root buffer removing the zval roots from there, and meanwhile, checks which zvals have been marked "white" in the previous step. Every zval marked as "white" will be freed

在来一次遍历, 删除白色节点

php.ini

zend.enable_gc = On

根缓存区有固定的大小, 可存 10000 个可能根, 当然你可以通过修改 PHP 源码文件 Zend/zend_gc.c 中的常量 GC_ROOT_BUFFER_MAX_ENTRIES

gc_enable()gc_disable() 函数
调用 gc_collect_cycles() 函数强制执行周期回收

在你调用 gc_disable() 函数释放内存之前, 先调用 gc_collect_cycles() 函数可能比较明智

时间: 2024-10-12 20:48:44

php 垃圾回收的相关文章

Java垃圾回收原理(2)

Java虚拟机采用一种自适应的垃圾回收技术.依据的思想:对任何"活"的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用.这个引用链条可能会穿过数个对象层次.由此,如果从堆栈和静态存储区开始,遍历所有的引用,就能找到所有活的对象.对于发现的每个引用,必须追踪它所引用的对象,然后是此对象所包含的所有的引用,如此反复进行,直到"根源于堆栈和静态存储区的引用"所形成的网络全部被访问为止.至于如何处理找到存活的对象,取决于不同的Java虚拟机的实现.有一种名为停止-复

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV

JavaGC专家(1)—深入浅出Java垃圾回收机制

在学习GC之前,你首先应该记住一个单词:"stop-the-world".Stop-the-world会在任何一种GC算法中发生.Stop-the-world意味着 JVM 因为要执行GC而停止了应用程序的执行.当Stop-the-world发生时,除了GC所需的线程以外,所有线程都处于等待状态,直到GC任务完成.GC优化很多时候就是指减少Stop-the-world发生的时间. 按代的垃圾回收机制 在Java程序中不能显式地分配和注销内存.有些人把相关的对象设置为null或者调用Sy

CMS垃圾回收机制

详解CMS垃圾回收机制 原创不易,未经允许,不得转载~~~ 什么是CMS? Concurrent Mark Sweep. 看名字就知道,CMS是一款并发.使用标记-清除算法的gc. CMS是针对老年代进行回收的GC. CMS有什么用? CMS以获取最小停顿时间为目的. 在一些对响应时间有很高要求的应用或网站中,用户程序不能有长时间的停顿,CMS 可以用于此场景. CMS如何执行?  总体来说CMS的执行过程可以分为以下几个阶段: 3.1 初始标记(STW) 3.2 并发标记 3.3 并发预清理

JVM那些事儿(二)——垃圾回收

这节小汪介绍一下jvm的垃圾回收机制,首先我们先提问: 1.为什么要有不同的垃圾算法 2.垃圾回收器要解决的终极目的是什么 3.小汪该如何选择自己的垃圾回收器 一.垃圾回收算法 众所周知,java堆内存的垃圾回收由java虚拟机管理,目前java有几种算法用来解决垃圾回收(以下只介绍最重要的两个算法) 1.1 复制算法 如图所示,复制算法可以说是最直观最简洁的算法了.按照复制算法的思路,内存要分为两块 Eden Survivor区域,Eden有一个,Survivor有两个. 首先,各种对象都在E

终结处理和垃圾回收(1)

之前一直不了解Java的垃圾回收原理,最近看了Java编程思想,有点想法,做做笔记. 首先,我们都了解初始化的重要性,但是常常会忘记同样也重要的清理工作.Java有垃圾回收器负责回收无用对象占用的内存资源.但是也有特殊情况:假定你的对象(并非使用new)获得一块"特殊"的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道如何释放该对象的这块特殊内存.为了应对这种情况,Java允许在类中定义一个名为finalize()方法. Java的finalize()不同于C+

Java 垃圾回收机制(早期版本)

Java 垃圾回收机制在我们普通理解来看,应该视为一种低优先级的后台进程来实现的,其实早期版本的Java虚拟机并非以这种方式实现的. 先从一种很简单的垃圾回收方式开始. 引用计数 引用计数是一种简单但是速度很慢的垃圾回收技术. 每个对象都含有要给引用计数器,当有引用连接至对象时,引用计数+1. 当引用离开作用域或者被置为null时,引用计数-1. 当发现某个对象的引用计数为0时,就释放其占用的空间.   这种方法开销在整个程序生命周期中持续发生,并且该方法有个缺陷,如果对象之间存在循环引用,可能

Python中的垃圾回收机制

当我们声明一个对象的时候,例如str="abcdef",当我们不再使用str这个对象的时候,这个对象就是一个脏对象,垃圾对象,但是它还在占着内存,毕竟我们的电脑内存有限,所以应该有一个机制来回收它以及类似的对象.现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的方式.自己管理内存极其自由,可以任意申请内存,但如同一把双刃剑,为大量内存泄露,悬空指针等bug埋下隐患. 对于一个字符串.列表.类甚至数值都是对象,且定位简单易用的语言,自然不会

JVM垃圾回收2(垃圾收集算法)

根据<深入理解java虚拟机>这本书总结 一.关于几个概念:(标记垃圾算法.垃圾收集算法.垃圾收集器) 前面说了如何寻找jvm垃圾,有两种方法:引用计数法/可达性算法.这篇准备讲,标记完垃圾之后,回收的算法,这里的算法只是垃圾回收的思想.后面会讲到多种垃圾收集器,这里的垃圾收集器就是运用了垃圾手机算法的思想,可以说是具体实现. 这里还是想多余的说一下这三个概念: 垃圾标记算法:标记垃圾的方法 垃圾收集算法:一种回收思想,供垃圾收集器使用.可能用在年轻代,也可能用在老年代(当然现在来说老年代和年

深入理解JAVA虚拟机之JVM性能篇---垃圾回收

一.基本垃圾回收算法 1. 按基本回收策略分 1) 引用计数(Reference Counting)  对象增加一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. 2)标记-清除(Mark-Sweep)  执行分两阶段.第一阶段从引用根节点开始标记所有被引用的对象,第二阶段遍历整个堆,把未标记的对象清除. 缺点是此算法需要暂停整个应用,同时会产生内存碎片. 3)复制(Copying) 把内存空间划为两个相等的区域,每