之前的文章中,我们已经学习过引用和引用传值相关的知识。我们知道,PHP 中没有纯引用(指针),不管是对象,还是用引用符号 & 赋值的变量,都是对一个符号表的引用。而今天,我们要学习的是另一种引用形式:弱引用。

什么是弱引用

弱引用允许程序员保留对对象的引用,而该对象不会阻止对象被销毁;它们对于实现类似缓存的结构非常有用。

这是比较官方的解释。从这个说明中,我们可以看出,弱引用也是一种引用形式,但是,如果我们销毁了原来的对象,那么弱引用对象也会被销毁,就像普通的值对象赋值一样。如果没有看过之前的文章,或者对 PHP 中的引用不太熟悉的朋友可能需要再了解一下 PHP 中引用相关的知识。下面,我们直接通过示例来看一下。

WeakReference

$obj = new stdClass;
$weakref = $obj; var_dump($weakref);
// object(stdClass)#1 (0) {
// } unset($obj);
var_dump($weakref);
// object(stdClass)#1 (0) {
// } $obj1 = new stdClass;
$weakref = WeakReference::create($obj1); var_dump($weakref->get());
// object(stdClass)#2 (0) {
// } unset($obj1);
var_dump($weakref->get());
// NULL $weakref = WeakReference::create(new stdClass);
var_dump($weakref->get());
// NULL

第一个对象 \$obj 我们进行直接的赋值引用,也就是 PHP 默认的对象赋值。这时候,$weakref 保存的是对象符号表的引用。当我们 unset() 掉 $obj 时,$weakref 依然能够正常使用。也就是说,$weakref 对 $obj 原始对象的内存引用依然保持着。不管我们怎么 unset() 原始的 $obj ,都只是切断了 $obj 的引用符号表,对真正的对象没有影响,垃圾回收器也不会彻底的回收最最原始的 $obj 对象内容。

第二个对象我们使用的是 WeakReference 的 create() 方法来创建的弱引用,当我们销毁 $obj1 后,$weakref 也会变成 NULL 。这就是弱引用的作用!

它可以让垃圾回收器正常的回收,它可以避免循环引用带来的内存泄漏问题,它能让引用表现为类似于 C 中的指针操作一样。

最后一段代码是我们通过 WeakReference::create() 中直接使用 new 来创建对象。这种形式是不行的,会一直返回 NULL 。因为弱引用是通过变量来创建的,它指向的是原始对象的符号表,而变量和对象之间的符号表连接才是弱引用关心的内容,它会根据符号表的状态来判断当前的状态。如果原始对象变量切断了与符号表的连接,那么弱引用的变量也会同步切断,这样,垃圾回收器就能正常的清理这个已经没有任何引用计数的对象了。

注意

这里需要注意的是,上面的测试代码必须在 PHP7.4 及以上版本才有用,WeakReference 类是 PHP7.4 新增加的内容。之前的版本需要安装 WeakRef 这个扩展才能实现弱引用的能力,具体的内容可以查阅下方链接中的相关的文档。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202006/source/%E5%AD%A6%E4%B9%A0PHP%E5%BC%B1%E5%BC%95%E7%94%A8%E7%9A%84%E7%9F%A5%E8%AF%86.php

参考文档:

https://www.php.net/manual/en/class.weakreference.php

https://www.php.net/manual/zh/book.weakref.php

学习PHP弱引用的知识的更多相关文章

  1. Java学习之强引用,弱引用,软引用 与 JVM

    1.java内存管理分为内存分配和内存回收,都不需要程序员负责. 2.垃圾回收的机制主要是看对象是否有引用指向该对象.  java对象的引用包括  强引用 软引用 弱引用 虚引用 3.强引用 是指创建 ...

  2. 九、Android学习笔记_ Android开发中使用软引用和弱引用防止内存溢出

    在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...

  3. C#学习笔记(十四):GC机制和弱引用

    垃圾回收(GC) 垃圾回收即Garbage Collector,垃圾指的是内存中已经不会再使用的对象,通过收集释放掉这些对象占用的内存. GC以应用程序的root为基础,遍历应用程序在Heap上动态分 ...

  4. JVM学习之强引用、弱引用、软引用、虚引用

    转自:http://my.oschina.net/ydsakyclguozi/blog/404389 多谢博主分享 1.强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象 ...

  5. Android学习笔记之SoftReference软引用,弱引用WeakReference

    SoftReference可以用于bitmap缓存 WeakReference 可以用于handler 非静态内部类和匿名内部类容易造成内存泄漏 private Handler mRemoteHand ...

  6. Android学习笔记_78_ Android开发中使用软引用和弱引用防止内存溢出

    在<Effective Java 2nd Edition>中,第6条“消除过期的对象引用”提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象 ...

  7. Java学习|强引用,软引用,弱引用,幻想引用有什么区别?

    在Java语言中,除了基本数据类型外,其他的都是指向各类对象的对象引用:Java中根据其生命周期的长短,将引用分为4类. 1 强引用 特点:我们平常典型编码Object obj = new Objec ...

  8. 【JVM学习】3.深入解析强引用、软引用、弱引用、幻象引用

    来源:公众号:猿人谷 关于强引用.软引用.弱引用.幻象引用的区别,在很多公司的面试题中经常出现,可能有些小伙伴觉得这个知识点比较冷门,但其实大家在开发中经常用到,如new一个对象的时候就是强引用的应用 ...

  9. weak 弱引用的实现方式

    来源:冬瓜争做全栈瓜 链接:https://desgard.com/weak/ 对于 runtime 的分析还有很长的路,最近在写 block 系列的同时,也回顾一下之前疏漏的细节知识.这篇文章是关于 ...

随机推荐

  1. Using Evernote with Wine on Mint

    Install Evernote Install Evernote in Wine: wine Evernote_xxx.exe; Backup Evernote Database File Loca ...

  2. STM32_从SystemInit、__main到main()

    STM32 的 SystemInit() 和 __main Author by [YuCloud](https://www.cnblogs.com/yucloud/) 上篇文章 STM32启动代码分析 ...

  3. awk-08-综合例子

    分析nginx日志 1.统计访问IP次数 2.统计访问IP大于10次的 3.统计访问IP次数,并取出前几的访问数 4.统计时间段访问最多的IP 5.统计访问最多的10个页面 6.统计每个 URL 数量 ...

  4. Sqli-Labs less29-31

    Less-29 可以从介绍上看出,第29关被称为世界上最好的WAF,网上许多讲解的办法就是和第一关差不多,其实是不对的. sqli-labs文件夹下面还有tomcat文件,这才是真正的less,里面的 ...

  5. IM敏感词算法原理和实现

    效果 C++实现的代码请移步: Github-cpp-dirtyfilter 用法和效果: int main() { std::vector<std::string> words = { ...

  6. Java实现WebSocket服务

    一.使用Tomcat提供的WebSocket库  Java可以使用Tomcat提供的WebSocket库接口实现WebSocket服务,代码编写也非常的简单.现在的H5联网游戏基本上都是使用WebSo ...

  7. noip模拟12[简单的区间·简单的玄学·简单的填数]

    noip模拟12 solutions 这次考试靠的还是比较好的,但是还是有不好的地方, 为啥嘞??因为我觉得我排列组合好像白学了诶,文化课都忘记了 正难则反!!!!!!!! 害没关系啦,一共拿到了\( ...

  8. mpu6050控制舵机云台

    准备材料:2个舵机mg90,云台支架,1个arduino-uno,mpu6050 编程工具:VScode-platformio  or  ArduinoIDE 我使用的是VScode在编辑代码上会更方 ...

  9. 详解C#中 Thread,Task,Async/Await,IAsyncResult的那些事儿

    说起异步,Thread,Task,async/await,IAsyncResult 这些东西肯定是绕不开的,今天就来依次聊聊他们 1.线程(Thread) 多线程的意义在于一个应用程序中,有多个执行部 ...

  10. apche的BeanUtils避免使用!

    原文出处 建议,不要使用apache的BeanUtils进行属性拷贝了,建议使用Spring 核心包bean下面的BeanUtils进行替代! 使用和对比出处