掌握PHP垃圾回收机制详解

php的垃圾回收机制可以简单总结为 引用计数 写时复制 COW机制,

本文主要和大家分享掌握php垃圾回收机制的知识,希望能帮助到大家。

引用计数基本知识

官网的解答如下 每个php变量存在一个叫”zval”的变量容器中一个zval变量容器,除了包含变量的类型和值 ,还包括两个字节的额外信息 is_ref 和 refcount is_ref 是个bool值,用来标识这个变量是否是属于引用集合(reference set)。通过这个字节,php引擎才能把普通变量和引用变量区分开来 refcount 用以表示指向这个zval变量容器的变量个数 PHP5 中的引用计数在PHP5中,zval 的内存是单独从堆(heap)中分配的(有少数例外情况),PHP 需要知道哪些 zval 是正在使用的,哪些是需要释放的。所以这就需要用到引用计数:zval 中 refcount__gc 的值用于保存 zval 本身被引用的次数,比如 b = 12语句中,12 被两个变量引用,所以它的引用计数就是 2。如果引用计数变成 0,就意味着这个变量已经没有用了,内存也就可以释放了。

如下:

<?php
//php zval变量容器
$a = 1;
$b = 1;
$c = &$a;
$d = $b;
$e = range(0, 3);
xdebug_debug_zval('a');
 xdebug_debug_zval('b');
xdebug_debug_zval('c');
 xdebug_debug_zval('d');
 xdebug_debug_zval('e'); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 结果如下
a:(refcount=2, is_ref=1),int 1b:(refcount=2, is_ref=0),int 1c:(refcount=2, is_ref=1),int 1d:(refcount=2, is_ref=0),int 1e:(refcount=1, is_ref=0), array (size=4) 0 => (refcount=1, is_ref=0),int 0 1 => (refcount=1, is_ref=0),int 1 2 => (refcount=1, is_ref=0),int 2 3 => (refcount=1, is_ref=0),int 3

每一个变量都记了自己的数PHP7 中的 zval在 PHP7 中 zval 有了新的实现方式。最基础的变化就是 zval 需要的内存不再是单独从堆上分配,不再自己存储引用计数。复杂数据类型(比如字符串、数组和对象)的引用计数由其自身来存储。这种实现方式有以下好处:简单数据类型不需要单独分配内存,也不需要计数不会再有两次计数的情况,在对象中,只有对象自身存储的计数是有效的由于现在计数由数值自身存储,所以也就可以和非 zval 结构的数据共享,比如 zval 和 hashtable key 之间间接访问需要的指针数减少了

<?php
//php zval变量容器
$a = 1;
$b = 1;
$c = &$a;
$d = $b;
$e = range(0, 3);
xdebug_debug_zval('a');
 xdebug_debug_zval('b');
xdebug_debug_zval('c');
 xdebug_debug_zval('d');
xdebug_debug_zval('e'); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 结果如下 a:(refcount=2, is_ref=1)int 1b:(refcount=0, is_ref=0)int 1c:(refcount=2, is_ref=1)int 1d:(refcount=0, is_ref=0)int 1e:(refcount=1, is_ref=0)array (size=4) 0 => (refcount=0, is_ref=0)int 0 1 => (refcount=0, is_ref=0)int 1 2 => (refcount=0, is_ref=0)int 2 3 => (refcount=0, is_ref=0)int 3

普通变量不再记自己的数,数组这样的复杂类型记自己的数什么是垃圾只有在准则3下,GC才会把zval收集起来,然后通过新的算法来判断此zval是否为垃圾。那么如何判断这么一个变量是否为真正的垃圾呢?简单的说,就是对此zval中的每个元素进行一次refcount减1操作,操作完成之后,如果zval的refcount=0,那么这个zval就是一个垃圾如果一个zval的refcount增加,那么此zval还在使用,不属于垃圾如果一个zval的refcount减少到0, 那么zval可以被释放掉,不属于垃圾如果一个zval的refcount减少之后大于0,那么此zval还不能被释放,此zval可能成为一个垃圾

以上所述是小编给大家介绍的PHP垃圾回收机制详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 总结PHP内存释放以及垃圾回收

    引用赋值 $a = 'apple'; $b = &$a; 上述代码中,我将一个字符串赋值给变量a,然后将a的引用赋值给了变量b.显然,这个时候的内存指向应该是这样的: $a -> 'apple' <- $b a和b指向了同一块内存区域,我们通过 var_dump($a, $b) 得到 string(5) "apple" string(5) "apple" ,这是我们预期的结果. unset 函数 假如我想将 'apple' 这个字符串从内存中释放

  • 简单谈谈PHP的垃圾回收机制

    1.每一个变量定义时都保存在一个叫zval的容器里面,这里面包含了数量的类型和和值,还包含了一个refcount(理解为存在几个变量个数)和is_ref(理解为是否为引用变量)两个额外信息,当变量被引用一次refcount就会+1,当你unset一下之后这个值就会减1直到为0就会从内存中删除 2.定义一个变量的时候并不是每次都会扩大预定于值,因为PHP会在内存中先预占用一个空间,等你声明变量的时候就会分配给你,但是当你超出这个预占用空间之后,那么它就会增加空间,但是等你删除变量时候这个空间容量不

  • 析构函数与php的垃圾回收机制详解

    析构函数:当某个对象成为垃圾或者当对象被显式销毁时执行. GC(Garbage Collector) 在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾.PHP会将其在内存中销毁. 这是PHP的GC(Garbage Collector)垃圾处理机制,防止内存溢出. 当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中的所有对象同样被销毁. __destruct() 析构函数 __destruct() 析构函数,是在垃圾对象被回收时执行. 析构函数也可以被显式调用,但不要这

  • PHP垃圾回收机制简单说明

    虽然自己也是PHP的学习者,但之前还真没怎么了解PHP内部的垃圾回收流程,只是在我们的代码中用了unset,null,mysql_close,__destruct等等一些函数去释放对象防止内存溢出而已,所以上网GG下,找到了以下一些说明,作下记录"PHP可以自动进行内存管理,清除不再需要的对象.PHP使用了引用计数(reference counting)这种单纯的垃圾回收(garbage collection)机制.每个对象都内含一个引用计数器,每个reference连接到对象,计数器加1.当r

  • 解读PHP中的垃圾回收机制

    PHP的基本GC概念 PHP语言同其他语言一样,具有垃圾回收机制.那么今天我们要为大家讲解的内容就是关于PHP垃圾回收机制的相关问题.希望对大家有所帮助.PHP strtotime应用经验之谈PHP memory_get_usage()管理内存PHP unset全局变量运用问题详解PHP unset()函数销毁变量教你快速实现PHP全站权限验证一.PHP 垃圾回收机制(Garbage Collector 简称GC) 在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾.PHP会将其在内存中

  • 深入解析PHP垃圾回收机制对内存泄露的处理

    上次说到了refcount和is_ref,这里来说说内存泄露的情况 复制代码 代码如下: $a = array(1, 2, &$a);unset($a); 在老的PHP版本中,这里就会出现内存泄露,分析如下: 执行第一行,可以知道$a和$a[2]指向的zval refcount=2,is_ref=1 然后执行第二行,$a将会从符号表中被删除,同时指向的zval的refcount--,此时refcount=1,因为refcount!=0,故此zval不会被当做垃圾回收,但是此时我们却失去了$a[2

  • Java 垃圾回收机制详解及实例代码

     Java 垃圾回收机制详解 乍一看,垃圾回收所做的事情应当恰如其名--查找并清除垃圾.事实上却恰恰相反.垃圾回收会跟踪所有仍在使用的对象,然后将剩余的对象标记为垃圾.牢记了这点之后,我们再来深入地了解下这个被称为"垃圾回收"的自动化内存回收在JVM中到底是如何实现的. 手动管理内存 在介绍现代版的垃圾回收之前,我们先来简单地回顾下需要手动地显式分配及释放内存的那些日子.如果你忘了去释放内存,那么这块内存就无法重用了.这块内存被占有了却没被使用.这种场景被称之为内存泄露. 下面是用C写

  • 掌握PHP垃圾回收机制详解

    php的垃圾回收机制可以简单总结为 引用计数 写时复制 COW机制, 本文主要和大家分享掌握php垃圾回收机制的知识,希望能帮助到大家. 引用计数基本知识 官网的解答如下 每个php变量存在一个叫"zval"的变量容器中一个zval变量容器,除了包含变量的类型和值 ,还包括两个字节的额外信息 is_ref 和 refcount is_ref 是个bool值,用来标识这个变量是否是属于引用集合(reference set).通过这个字节,php引擎才能把普通变量和引用变量区分开来 ref

  • python的内存管理和垃圾回收机制详解

    简单来说python的内存管理机制有三种 1)引用计数 2)垃圾回收 3)内存池 接下来我们来详细讲解这三种管理机制 1,引用计数: 引用计数是一种非常高效的内存管理手段,当一个pyhton对象被引用时其引用计数增加1,当其不再被引用时引用计数减1,当引用计数等于0的时候,对象就被删除了. 2,垃圾回收(这是一个很重要知识点): ①  引用计数 引用计数也是一种垃圾回收机制,而且是一种最直观,最简单的垃圾回收技术. 在Python中每一个对象的核心就是一个结构体PyObject,它的内部有一个引

  • Java基础之垃圾回收机制详解

    一.GC的作用 进行内存管理 C语言中的内存,申请内存之后需要手动释放:一旦忘记释放,就会发生内存泄漏! 而Java语言中,申请内存后会由GC来释放内存空间,无需手动释放 GC虽然代替了手动释放的操作,但是它也有局限性: 需要消耗更多的资源: 没有手动释放那么及时: STW(Stop The World)会影响程序的执行效率 二.GC主要回收哪些内存 (1)堆:主要回收堆中的内存 (2)方法区:需要回收 (3)栈(包括本地方法栈和JVM虚拟机栈):不需要回收,栈上的内存什么时候释放是明确的(线程

  • JVM的垃圾回收机制详解和调优

    文章来源:matrix.org.cn 作者:ginger547 1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作. 在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能.有些垃圾收集专用于特殊的应用程序.比如,实时应用程序主要是为了避免垃圾收集中断,而大多数OLTP应用程序则注重整体效率.理解了应用程序的工作负荷

  • Java 垃圾回收机制详解(动力节点Java学院整理)

    1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除内存记录碎片.由于创建对象和垃圾回收器释放丢弃对象所占的内存空间,

  • PHP进阶学习之垃圾回收机制详解

    本文实例讲述了PHP垃圾回收机制.分享给大家供大家参考,具体如下: 一.概念 垃圾回收机制是一种动态存储分配的方案.它会自动释放程序不再需要的已分配的内存块.垃圾回收机制可以让程序员不必过分关心程序内存分配,从而将更多的精力投入到业务逻辑.在现在的流行各种语言当中,垃圾回收机制是新一代语言所共有的特征,如Python.PHP.C#.Ruby等都使用了垃圾回收机制. 二.PHP垃圾回收机制 1.在PHP5.3版本之前,使用的垃圾回收机制是单纯的"引用计数".即: ①每个内存对象都分配一个

  • Python的垃圾回收机制详解

    引用计数 在Python源码中,每一个对象都是一个结构体表示,都有一个计数字段. typedef struct_object { int ob_refcnt; struct_typeobject *ob_type; } PyObject; PyObject是每个对象必有的内容,其中ob_refcnt就是作为引用计数.当一个对象有了新的引用时,它的ob_refcnt就会增加,引用它的对象被删除时则减少.一旦对象的引用计数为0,该对象立即被回收,占用空间就会被释放. 优点 简单易用 实时性好,一旦没

  • Java 中的垃圾回收机制详解

    目录 介绍 重要条款: 使对象符合 GC 条件的方法 请求JVM运行垃圾收集器的方式 定稿 总结 介绍 在 C/C++ 中,程序员负责对象的创建和销毁.通常程序员会忽略无用对象的销毁.由于这种疏忽,在某些时候,为了创建新对象,可能没有足够的内存可用,整个程序将异常终止,导致OutOfMemoryErrors. 但是在 Java 中,程序员不需要关心所有不再使用的对象.垃圾回收机制自动销毁这些对象. 垃圾回收机制是守护线程的最佳示例,因为它始终在后台运行. 垃圾回收机制的主要目标是通过销毁无法访问

  • Python 垃圾回收机制详解

    目录 1. 引用计数 2. 标记-清除 3. 分代回收 4. 其他 4.1 JNI(Java Native Interface) 总结 Python 的GC模块主要运用了引用计数来跟踪和回收垃圾:通过"标记-清除"解决容器对象可能产生的循环引用问题:通过分代回收以空间换时间进一步提高垃圾回收的效率. 也即采用"引用计数"为主(实时性,一旦没有引用,内存就直接释放了),"标记-清除"与"分代收集"两种机制为辅的策略.      

随机推荐