php 浅谈垃圾回收机制

php每创建一个变量,就会在zval中记录。一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息。

第一个是"is_ref",用来标识这个变量是否是属于引用集合(reference set), bool类型。

通过这个字节,php引擎才能把普通变量和引用变量区分开来,由于php允许用户通过使用&来使用自定义引用,zval变量容器中还有一个内部引用计数机制,来优化内存使用。

第二个额外字节是"refcount",用以表示指向这个zval变量容器的变量(也称符号即symbol)个数。所有的符号存在一个符号表中,其中每个符号都有作用域(scope),那些主脚本(比如:通过浏览器请求的的脚本)和每个函数或者方法也都有作用域。

安装Xdebug 来显示变量容器中的refcount 和 is_ref

demo1

<?php
$a = "hello world";
xdebug_debug_zval(‘a‘);输出:a:(refcount=1, is_ref=0)=‘hello world‘

新的变量a在当前作用域中生成了,同时生成了string类型 值为 ‘hello world’的变量容器。

将一个变量赋值给另外一个变量时会增加引用次数。

demo2

<?php
$a = "hello world";
$b = $a;
xdebug_debug_zval( ‘a‘ );输出:a: (refcount=2, is_ref=0)=‘hello world‘

输出发现refcount变成了2,同一个变量容器被$a和$b关联。在非必要时,php是不会复制已经生成的变量容器的,当refcount=0时,变量容器就会被销毁。

当任何关联到某个变量容器的变量离开它的作用域(函数执行结束)、或者对变量使用了unset()时,refcount就会-1

demo3

<?php
$a = "hello world";
$c = $b = $a;
xdebug_debug_zval( ‘a‘ );
unset( $b, $c );
xdebug_debug_zval( ‘a‘ );
输出:
a: (refcount=3, is_ref=0)=‘hello world‘
a: (refcount=1, is_ref=0)=‘hello world‘

如果我们现在执行unset($a);,包含类型和值的这个变量容器就会从内存中删除。

复合类型:

demo4

<?php
$a = array( ‘name‘ => ‘life‘, ‘num‘ => 11 );
xdebug_debug_zval( ‘a‘ );
输出:
a: (refcount=1, is_ref=0)=array (
   ‘name‘ => (refcount=1, is_ref=0)=‘life‘,
   ‘num‘ => (refcount=1, is_ref=0)=11
)

这三个zval变量容器是:a,name,num

添加一个已经存在的元素到数组中:

demo5

<?php
$a = array( ‘name‘ => ‘life‘, ‘num‘ => 11 );
$a[‘life‘] = $a[‘name‘];
xdebug_debug_zval( ‘a‘ );
输出:
a: (refcount=1, is_ref=0)=array (
   ‘name‘ => (refcount=2, is_ref=0)=‘life‘,
   ‘num‘ => (refcount=1, is_ref=0)=11,
   ‘life‘ => (refcount=2, is_ref=0)=‘life‘
)

发现name和life的refcount都变成了2,但是life是新添加的,说明值为‘life‘的zval变量容器其实是同一个,xdebug_debug_zval()并没有显示这个信息。删除其中一个元素,另一个的refcount也会减少,废话不多说,上demo

demo6

<?php
$a = array( ‘name‘ => ‘life‘, ‘num‘ => 11 );
$a[‘life‘] = $a[‘name‘];
unset( $a[‘name‘], $a[‘num‘] );
xdebug_debug_zval( ‘a‘ );
输出:
a: (refcount=1, is_ref=0)=array (
   ‘life‘ => (refcount=1, is_ref=0)=‘life‘
)

这样发现,一直都是refcount的值在改变,is_ref的值一直是false,当使用传引用的时is_ref的值才会发生变化。

其他的回收周期或者性能方面的考虑,有时间再不伤

原文地址:https://www.cnblogs.com/pfdltutu/p/9028604.html

时间: 2024-07-31 21:00:46

php 浅谈垃圾回收机制的相关文章

浅谈垃圾回收机制

C/C++经典垃圾回收算法 1. 引用计数法: 每个对象计算指向它的指针数量 当有一个指针指向自己时数值加1 当删除一个指向自己的指针时计数减1 如果减为0,说明已经不存在指向该对象的指针了,所以可以安全销毁了. 2. 标记-清除算法 3. 标记-缩并算法 4. 节点拷贝算法 引用计数法能够平滑的进行垃圾回收,而不出现"停止"现象,经常出现于一些实时系统中,但它无法解决环形问题. 后面三种统称为跟踪垃圾回收,在每一次垃圾回收过程中,要遍历或者复制所有存活的对象,这是一个非常耗费时间和空

浅谈Chrome V8引擎中的垃圾回收机制

垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带来的内存泄露问题.但使用了垃圾回收即意味着程序员将无法掌控内存.ECMAScript没有暴露任何垃圾回收器的接口.我们无法强迫其进 行垃圾回收,更无法干预内存管理 内存管理问题 在浏览器中,Chrome V8引擎实例的生命周期不会很长(谁没事一个页面开着几天几个月不关),而且运行在用户的机器上.如果

垃圾回收机制GC知识再总结兼谈如何用好GC(其他信息: 内存不足)

来源 一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: 1.手动管理:C,C++ 2.计数管理:COM 3.自动管理:.NET,Java,PHP,GO- 但是,手动管理和计数管理的复杂性很容易产生以下典型问题: 1.程序员忘记去释放内存 2.应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱码,而且大部分时候,

垃圾回收机制GC知识再总结兼谈如何用好GC

一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般有如下几种: 1.手动管理:C,C++ 2.计数管理:COM 3.自动管理:.NET,Java,PHP,GO… 但是,手动管理和计数管理的复杂性很容易产生以下典型问题: 1.程序员忘记去释放内存 2.应用程序访问已经释放的内存 产生的后果很严重,常见的如内存泄露.数据内容乱码,而且大部分时候,程序的

java的垃圾回收机制的特点

浅谈java的垃圾回收机制的特点: 1.垃圾回收机制的目标是回收无用对象的内存空间(记住:不是对象),这些内存空间是JVM堆内存的内存空间.垃圾回收只回收内存资源,对于那些物理资源,如数据库连接,Socket,I/O流等资源无能无能为力,我们要自己关闭回收. 2.为了加快垃圾回收机制回收那些无用对象所占的内存空间,我们可以讲对象的引用变量置于null(记住:置于null后,垃圾回收机制不会立即执行的). 3.垃圾回收机制的潜在缺点它的开销会影响性能.Java虚拟机必须跟踪程序中有用的对象才可以确

PHP垃圾回收机制的理解

PHP垃圾回收机制是php5之后才有的这个东西,下面我来给大家介绍一下关于PHP垃圾回收机制一些理解,希望对各位同学有所帮助. php 5.3之前使用的垃圾回收机制是单纯的"引用计数",也就是每个内存对象都分配一个计数器,当内存对象被变量引用时,计数器 1:当变量引用撤掉后,计数器-1:当计数器=0时,表明内存对象没有被使用,该内存对象则进行销毁,垃圾回收完成. "引用计数"存在问题,就是当两个或多个对象互相引用形成环状后,内存对象的计数器则不会消减为0:这时候,这

JavaScript中的垃圾回收机制

什么是js垃圾回收?(what) JavaScript中也具有自动垃圾回收机制(GC:Garbage Collection); 因为内存内容是极其有限的,所以垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放内存 其中不再使用的变量一般只可能是局部变量,即在函数执行结束的时候,所使用的局部变量所占的内存会随之被回收,当然在闭包中内部函数会占用着外部函数的局部变量. 有哪些垃圾回收方式?(how) 到底哪个变量是没有用的?所以垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标

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

4.5-全栈Java笔记:垃圾回收机制

垃圾回收机制(Garbage  Collection) Java引入了垃圾回收机制,令C++程序员最头疼的内存管理问题迎刃而解.JAVA程序员可以将更多的精力放到业务逻辑上而不是内存管理工作上,大大的提高了开发效率. 垃圾回收原理和算法 1)内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可.垃圾回收器将负责回收所有"不可达"对象的内存空间. 2)垃圾回收过程 任何