垃圾回收:

简称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

GC处理完整流程图

gc机制 php7_PHP7垃圾回收机制详解(附GC处理完整流程图)相关推荐

  1. GC garbage collection 垃圾回收机制

    GC  garbage collection   垃圾回收机制 1 找到内存空间中的垃圾. 2.回收垃圾,让程序员可以再次利用. 满足这样的程序就是GC GC的评价性能的标准: 1吞吐量2 最大暂停时 ...

  2. JVM内存管理机制和垃圾回收机制

    JVM内存管理机制和垃圾回收机制 JVM结构 图片描述: java源码编译成class文件 class文件通过类加载器加载到内存 其中方法区存放的是运行时的常量.静态变量.类信息等,被所有线程共享 堆 ...

  3. JVM之垃圾回收算法详解

    JVM之垃圾回收算法详解 现有的垃圾回收算法 分类 垃圾收集器的设计原则 标记-清除算法 缺点 标记-复制算法 "Apple回收策略" 缺点 标记-整理算法 缺点 总结 现有的垃圾 ...

  4. php7垃圾回收机制l_PHP7 垃圾回收机制(GC)解析

    垃圾回收机制 垃圾回收机制是一种动态存储分配方案.它会自动释放程序不再需要的已分配的内存块. 自动回收内存的过程叫垃圾收集.垃圾回收机制可以让程序员不必过分关心程序内存分配,从而将更多的精力投入到业务 ...

  5. java gc 可达性_JAVA--GC 垃圾回收机制----可达性分析算法

    在JVM 中,java 为我们提供可有效的垃圾回收机制,GC ,GC的创建无疑是为了缓解内存压力.保存有效数据.回收垃圾无效数据: 在此之前GC在我的理解中,一直只是个概念,内存中出现垃圾,GC来回收 ...

  6. python的几种重要机制(垃圾回收机制,猴子补丁,反射机制,自省机制)

    python垃圾回收机制 垃圾回收机制要解决的问题 内存泄漏 悬空指针 引用计数 定义 环形链表中所存放数据的相同点和不同点 无法解决循环引用问题 标记清除 原理: 存在查找活动对象效率低下的问题 隔 ...

  7. JVM底层原理+四大垃圾回收算法详解-周阳老师

    转载自,感谢原作者:https://www.jianshu.com/p/9e6841a895b4 注意:垃圾回收算法周阳老师讲的有错误,具体在p19,四大垃圾回收算法为复制算法.标记-整理算法.标记- ...

  8. 深度解析Python的内存管理机制:垃圾回收机制

    Python程序在运行时,需要在内存中开辟出一块空间,用于存放运行时产生的临时变量,计算完成后,再将结果输出到永久性存储器中.但是当数据量过大,或者内存空间管理不善,就很容易出现内存溢出的情况,程序可 ...

  9. python 内存回收机制_Python垃圾回收机制是什么

    不同于C/C++,像Python这样的语言是不需要程序员写代码来管理内存的,它的GC(Garbage Collection)机制 实现了自动内存管理.GC做的事情就是解放程序员的双手,找出内存中不用的 ...

最新文章

  1. 基于wincc的虚拟电梯设计_基于WINCC的模拟电梯设计
  2. 今日 Paper | 社交媒体谣言检测;连续手语识别;细粒度服装相似性学习;混合图神经网络等
  3. 汉字转UNICODE?
  4. 13产品经理要懂的-人性的恶要怎么利用
  5. 怎么理解高内聚低耦合
  6. 中国大数据与智能计算产业联盟“开源软件工作委员会”成立会议在京召开
  7. 宗成庆统计自然语言处理第二版第13章读书笔记-文本分类与情感分类
  8. python数据分析入门到实战 知了课堂 百度云_零基础入门Python数据分析,只需要看懂这一张图,附下载链接!...
  9. golang c10k问题
  10. LTE中QPSK、16QAM、64QAM什么意思?有什么区别,分别在什么情况下占用呢?
  11. Python制作经典的吃豆豆小游戏
  12. Ps照片一键生成彩铅马克笔手绘效果图方法
  13. Wifi流程机制分析:WiFi的启动
  14. 【科普】浅谈NB-IoT
  15. 推荐5个程序员专属的开源APP
  16. 视频无法播放是怎么回事
  17. ROS控制桌面机械手Dobot魔术师
  18. Jerry Wang的SAP工作日志 - 2016年1月
  19. PWN passcode [pwnable.kr]CTF writeup题解系列5
  20. python matplotlib包_Python matplotlib-venn包_程序模块 - PyPI - Python中文网

热门文章

  1. Python python 五种数据类型--字符串
  2. 类的继承 设计模式
  3. IDEA里如何安装Python插件打造开发环境(图文详解)
  4. codeforces 688D D. Remainders Game(中国剩余定理)
  5. c# winform 点击按钮切换tabcontrol标签
  6. Verilog HDL中阻塞语句和非阻塞语句的区别
  7. C# 使用Bitmap类进行图片裁剪
  8. 优秀程序员的两大要素:懒 + 笨
  9. SemVLP 单流和双流Transformer哪个好?阿里:我全都要!提出带可插拔模块的Transformer结构...
  10. 除了 Tensorflow、PyTorch ,还有哪些深度学习框架值得期待?