百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

5分钟轻松搞懂php7垃圾回收机制(php7垃圾回收机制简述)

moboyou 2025-08-02 20:11 5 浏览

目录

  • 概述
  • php7垃圾回收机制详解
  • php7进阶到架构师相关阅读

概述

这是关于php进阶到架构之php7性能优化学习的第篇文章:5分钟轻松搞懂php7垃圾回收机制

php7垃圾回收机制详解

垃圾回收:

简称GC。顾名思义,就是废物重利用的意思。说垃圾回收机制之前,先接触一下内存泄漏。

内存泄漏:

某大神重口味充满画面感的形象解释:

大概意思就是申请了一块地儿拉了会儿屎,拉完后不收拾,那么那块儿地就算是糟蹋了,地越用越少,最后一地全是屎。说到底一句,用了记得还。一定程度上说,垃圾回收机制就是用来擦屁股的。

c语言垃圾回收机制:

如果用过C语言,那么申请内存的方式是malloc或者是calloc,然后你用完这个内存后,一定不要忘了用free函数去释放掉,这就是手动垃圾回收,一般都是大神用这种方式。

php的自动垃圾回收机制是怎样的呢?

这个问题我们先这么想,我们都知道php是C语言实现的。你想想如何用C语言实现对一个变量的统计以及释放。C语言是如何实现一个变量,从声明开始到最后没人用了,就把这个变量所占的内存给释放掉(被垃圾回收)。

PHP进行内存管理的核心算法一共两项:一是引用计数,二是写时拷贝

声明一个PHP变量的时候,C语言就在底层生成一个叫做zval的struct(结构体),如下:

zval {
string "a" //变量的名字是a
value zend_value //变量的值,联合体
type string //变量是字符串类型
}

zval struct结构体:

(1)保存php $a的变量名

(2)php $a的变量类型

(3)php变量$a的zend_value联合体

如果给变量赋值了,比如“hello world”,那么C语言就在底层再生成一个叫做zend_value的union(联合体)

zend_value {
string "hello world" //值的内容
refcount 1 //引用计数
}

zend_value的union(联合体)

(1)保存php $a的变量的值hello world

(2)记录php $a变量引用次数

看到 zval struct结构体和zend_value,如果面试官问你php变量为什么能够保存字符串"123"也能保存数字123,你知道该怎么回答了吧?就答出重点zval中有该变量的类型,当是字符串123的时候,type就是string,此时value指向“123”;当是整数123的时候,zval的type为int,value为123。

何为引用计数?

代码实战解析php变量引用计数

$a = 'hello,world';
echo xdebug_debug_zval( 'a');//refcount=1
$b = $a;
echo xdebug_debug_zval( 'a'); //$b引用$a,故变量a,refcount=2
$c = $a;
echo xdebug_debug_zval( 'a'); //$c引用$a,故变量a,refcount=3
unset( $c );
echo xdebug_debug_zval( 'a');//删除了$c的引用,故变量a,refcount=2

运行结果:

a:(refcount=1, is_ref=0)string 'hello,world' (length=11)

a:(refcount=2, is_ref=0)string 'hello,world' (length=11)

a:(refcount=3, is_ref=0)string 'hello,world' (length=11)

a:(refcount=2, is_ref=0)string 'hello,world' (length=11)

何为拷贝复制?

$a = 'hello';
$b = $a;//$a赋值给$b的时候,$a的值并没有真的复制了一份
echo xdebug_debug_zval( 'a');//$a的引用计数为2
$a = 'world';//当我们修改$a的值为123的时候,这个时候就不得已进行复制,避免$b的值和$a的一样
echo xdebug_debug_zval( 'a');///$a的引用计数为1

运行结果:

a:(refcount=2, is_ref=0)string 'hello' (length=5)

a:(refcount=1, is_ref=0)string 'world' (length=5)

其实,当你把$a赋值给$b的时候,$a的值并没有真的复制了一份,这样是对内存的极度不尊重,也是对时间复杂度的极度不尊重,计算机仅仅是将$b指向了$a的值而已,这就叫多快好省。那么,什么时候真正的发生复制呢?就是当我们修改$a的值为123的时候,这个时候就不得已进行复制,避免$b的值和$a的一样。

通过简单的案例解释清楚了两个要点:引用计数和写时拷贝。

垃圾回收机制:

当一个zval在被unset的时候、或者从一个函数中运行完毕出来(就是局部变量)的时候等等很多地方,都会产生zval与zend_value发生断开的行为,这个时候zend引擎需要检测的就是zend_value的refcount是否为0,如果为0,则直接KO free空出内容来。如果zend_value的recount不为0,这个value不能被释放,但是也不代表这个zend_value是清白的,因为此zend_value依然可能是个垃圾。

(1)当php变量$a的refcount=0时,变量$a就会被垃圾回收

(2)当php变量$a的refcount>0时,变量$a也可能被认为是垃圾

什么样的情况会导致zend_value的refcount不为0,但是这个zend_value却是个垃圾呢?

$arr = [ 1 ];
$arr[] = &$arr;
unset( $arr );

这种情况下,zend_value不会能释放,但也不能放过它,不然一定会产生内存泄漏,所以这会儿zend_value会被扔到一个叫做垃圾回收堆中,然后zend引擎会依次对垃圾回收堆中的这些zend_value进行二次检测,检测是不是由于上述两种情况造成的refcount为1但是自身却确实没有人再用了,如果一旦确定是上述两种情况造成的,那么就会将zend_value彻底抹掉释放内存。

垃圾回收发生在什么时候?

有些同学可能有疑问,就是php不是运行一次就销毁了吗,我要gc有何用?并不是的,首先当一次fpm运行完毕后,最后一定还有gc的,这个销毁就是gc;其次是,内存都是即用即释放的,而不是攒着非得到最后,你想想一个典型的场景,你的控制器里的某个方法里用了一个函数,函数需要一个巨大的数组参数,然后函数还需要修改这个巨大的数组参数,你们应该是函数的运行范围里面修改这个数组,所以此时会发生写时拷贝了,当函数运行完毕后,就得赶紧释放掉这块儿内存以供给其他进程使用,而不是非得等到本地fpm request彻底完成后才销毁。

(1)fpm运行完毕后,最后一定会gc的

(2)运行过程中,也会gc的,内存都是即用即释放的,而不是攒着非得到最后gc

php7进阶到架构师相关阅读

php7进阶到架构师相关阅读

https://www.kancloud.cn/gofor/gofor

相关推荐

六星教育PHP大神进阶班怎么样?值不值得去听?

点进这篇文章的人可能现在正面临着几个很难选择的问题,比如学PHP要不要报培训班?或者是该怎样选择PHP课程?又或是六星教育的PHP大神进阶班好不好,能不能去?在这里就给你们都一个一个解答了!首先,要...

PHP开发是什么?兄弟连教你学PHP(php开发技术)

如果说每种语言都千秋各异,那么PHP开发有太多的原因使得PHP成为世界上最受欢迎的脚本语言——高度灵活、简单易用——不过写PHP(或者任何这种语言)代码时,人们常常陷入单调重复而令人生厌的体力活动的窘...

参加PHP培训,主要学哪些课程?(php培训课程内容)

PHP语言是编程语言里十分热门的一种语言,其特性引来了很多编程爱好者进行学习,同时PHP语言的发展前景也非常好,这让很多学员都是蠢蠢欲动,如果去PHP培训班学习,主要是学什么内容呢?下面以六星教育PH...

小狐狸ChatGPT付费创作系统V2.4.7全开源版 (vue全开源端)

测试环境:Nginx1.20+PHP7.4+MySQL5.7本版本为官方的最新开源包对应V2.4.7版本,包含了前后端所有开源包,是目前最新全开源版本,需要二开的这部分朋友也有选择了,如果不需要二...

NETCore部署linux入魔Docker+Jenkins

通过前面三篇:.NETCore部署到linux(CentOS)最全解决方案,常规篇.NETCore部署到linux最全解决方案,进阶篇(Supervisor+Nginx).NETCore部署到l...

柏拉图性格测试源码如何修改为自己使用

昨天,性格测试图片火爆了整个朋友圈。同时也急坏了公众号运营者,这么神奇的东东是怎么弄的,我们也要。好吧,我来拯救广大运营同志们工具/原料电脑柏拉图性格测试源码dreamweaver公众号方法/步骤1解...

APP成品开发与定制开发的区别是什么?

APP成品开发与定制开发的区别是什么?APP成品开发也就是在成品APP基础上进行的开发,除此之外,还有APP半成品开发与定制开发这两种方式。APP成品开发、半成品开发与定制开发的区别是什么?今天我们一...

一套优质成品短视频APP的搭建部署,离不开的软硬编解码

一款优质的短视频APP诞生并非易事,开发过程也是需要考虑各种问题,包括音视频问题、开屏速度等等。无论是短视频还是直播,都要经过无数次的测试、优化等步骤完成。那么今天我们就来看一下,短视频直播源码如何利...

Java规则引擎风控系统全套成品源代码

可直接使用的企业级规则引擎,自动化与智能化并行。Java语言开发,前端VUE+ElementUI,提供私有化部署,支持提供全量源码、二次开发、定制、可集成。在线demo:http://rules.bc...

盲盒抽卡机小程序成品部署源码搭建支持定制支持二开

成品短视频app源码搭建教程,带你一步步实现开发

在当今数字化时代,短视频已经成为了人们热衷的内容形式。如果您有兴趣创建自己的短视频应用程序,但又不想从头开始开发,那么成品短视频app源码搭建是您的理想选择。本文将详细介绍成品短视频app源码搭建的好...

成品短视频App源码推荐,助力你的创业梦想

在当今数字化时代,短视频已经成为人们日常生活不可或缺的一部分。这种形式的内容创作在社交媒体平台上蓬勃发展,为用户提供了一种快速、有趣且易于消化的方式来获取信息和娱乐。如果你梦想着在这个领域进行创业,那...

深圳嘉华:PHP如何通过Web 执行C/C++应用程序方法

一、简介如果你对Unix/Linux有所了解的话,你应该知道他们大都自带了C和C++的编译器,分别是GCC和G++。Unix在程序安装及Make等许多地方使用到了这些编译器。利用一些控制台命令,C++...

PHP类Web网站适应移动设备十贴士(php主要用于开发基于浏览器/服务器结构的应用程序)

【编者按】相比较桌面端,用户越来越多的从移动设备端访问网页,这已经不是什么新鲜事。然而开发者还是需要努力去让网站更好的适应现在的移动设备,与此同时,从谷歌最近宣布的消息可以看出,它可能会惩罚那些不能为...

Web前端开发基础提要(web前端开发基础知识总结)

Web的项目页面功能越来越复杂,如何进行有效的多人协作,如何提高团队的开发效率,如何进行快速迭代,保证项目质量,前端工程就是为了满足这些需求,同时兼顾代码开发阶段,打包发布阶段,主要涉及组件化开发、...