PHP中的垃圾回收机制是如何运作的?它对程序性能有何具体影响?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2032个文字,预计阅读时间需要9分钟。
本篇文章向读者简要介绍垃圾回收,深入剖析PHP中的垃圾回收机制,最后探讨垃圾回收对性能的影响。让我们一起看看吧!
垃圾回收是自动管理内存的一种机制,用于回收不再使用的内存资源。在PHP中,垃圾回收器负责检测并释放不再被引用的对象所占用的内存。
PHP的垃圾回收机制主要基于引用计数和标记-清除两种方式。引用计数是指每个对象都有一个引用计数器,每当一个变量引用该对象时,计数器加一;当引用消失时,计数器减一。当计数器为零时,表示该对象不再被引用,垃圾回收器会释放其内存。
然而,引用计数存在循环引用的问题。为了解决这个问题,PHP还采用了标记-清除机制。在标记阶段,垃圾回收器会遍历所有活跃的对象,标记它们为可达。在清除阶段,垃圾回收器会释放所有未被标记为可达的对象所占用的内存。
垃圾回收对性能的影响主要体现在以下几个方面:
1. 引用计数法的开销:引用计数法需要维护每个对象的引用计数器,这会带来一定的性能开销。
2. 标记-清除的开销:标记-清除阶段需要遍历所有活跃的对象,这可能会影响性能。
3. 内存碎片:频繁的垃圾回收可能会导致内存碎片化,影响内存分配效率。
4. 停止-开始(Stop-The-World)问题:在垃圾回收过程中,应用程序可能会暂停执行,这被称为停止-开始问题。
总之,垃圾回收是PHP中一个重要的内存管理机制,它有助于提高程序的性能和稳定性。然而,过度依赖垃圾回收可能会带来一些性能问题。因此,开发者需要根据实际情况合理使用垃圾回收,以达到最佳的性能表现。
本篇文章给大家介绍一下垃圾回收,浅析PHP中垃圾回收机制,最后聊聊垃圾回收对性能的影响,一起开看看吧!相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个变量都会保存在内存中。其实,我们这些开发者就是在来回不停地操纵内存,相应地,我们如果一直增加新的变量,内存就会一直增加,如果没有一个好的机制,那么内存就会无限制地增加最终撑满所有的内存。这就造成了内存泄露。但在日常开发中,除非一次加载一个很大的文件,我们几乎见不到内存超限的错误,这就是垃圾回收机制的作用。
垃圾回收是什么东西?
在使用 C 语言的时候,我们都要手动使用 free 来释放内存,在 C 之后的大部分编程语言都会自带一个垃圾回收之类的处理能力,也就是我们今天要说的垃圾回收机制,也称为 GC 。在有 GC 能力的开发语言中,我们不需要去关心什么时候释放内存,甚至我们完全不需要去了解这一块的内容,因为这些语言在底层已经帮我们处理好了关于内存释放的问题。
当然这方面的内容最出名的就是 Java 中的垃圾回收机制,其实 PHP 也有相应的处理机制,当然,很多 PHPer 可能从来没接触过,今天我们就来探讨一下这方面的内容。
PHP 的垃圾回收算法
在之前的文章中,我们有介绍过引用计数的概念。在 PHP5.3 之前,PHP 的垃圾回收机制非常简单,就是把 refcount 为0的全部清理回收掉,在底层也就是 free 掉了。但是这种方式会带来一个问题,也就是我们在引用计数这篇文章中说过的循环引用,这种引用问题通过普通的判断 refcount 的方式是无法回收的。所以在 PHP5.3 之前,循环引用是会造成内存泄露的。
之所以强调版本,那是因为在 5.3 之后,PHP 改进了垃圾回收的算法,使这种循环引用得到了解决。(当然,我们在日常开发中尽量要避免这种循环引用的问题)。具体算法我们引用官方的图片:
在官方文档中有详尽的解释,不过还是会看得很懵逼。我们就用简单的语言(说人话)来描述这个过程。
首先,我们有个根缓冲区的概念,就是图中的 root 。在底层通过一系列看不懂搞不明白的算法我们能找到每个变量的一个可能根。PHP 会将变量的可能根放入根缓冲区。
当根缓冲区满了的时候,一般这个默认值是10000,需要修改源码重新编译才能修改这个值。PHP 就会启动垃圾回收机制,从根缓冲区中按照深度遍历的算法来查找所有的和这个可能根相关的变量,并将某一个可能根找到的变量的 refcount 减1,并做一个标记当前这个“已减”。
然后再次深度遍历,如果 refcount 不是0的,就加1,如果是0的就保持不变。
接着清除根缓冲区中的所有可能根,清除而不是删除。然后清理释放所有的 refcount 为0的变量内容。
是不是已经懵逼了?其实我也很懵逼,都不知道这段是怎么写下来的....
记住几个要点就可以对付面试并秒杀大部分人了。
- PHP5.3 后并不是直接看每个变量的 refcount 是否为0了
- 使用的算法是深度遍历,有个根缓冲区,根据它来清理,具体算法需要比较扎实的 C 和算法基础,学源码的时候再好好研究吧
- 5.3 之后和算法解决了循环引用的问题
- 内存泄露值会保持在某一个范围,不会出现立即大范围崩溃的情况
垃圾回收对性能的影响
前文说过,垃圾回收在根缓冲区满了之后会马上执行。其中也会进行两次的深度遍历,这就不可避免的带来了性能的消耗。毕竟算法的执行都是需要耗时的。不过相对于内存溢出这种毁灭性的错误来说,垃圾回收带来的性能损耗基本上是可以忽略不计的。
总结
垃圾回收的内容其实我们只需要记住几个关键点就可以了,具体的核心算法和内容是需要在更深入的研究源码后才能完全了解的,当然,这也是我们学习的目标,之后也一定会涉猎源码底层的相关内容,就让我们拭目以待吧!
本文共计2032个文字,预计阅读时间需要9分钟。
本篇文章向读者简要介绍垃圾回收,深入剖析PHP中的垃圾回收机制,最后探讨垃圾回收对性能的影响。让我们一起看看吧!
垃圾回收是自动管理内存的一种机制,用于回收不再使用的内存资源。在PHP中,垃圾回收器负责检测并释放不再被引用的对象所占用的内存。
PHP的垃圾回收机制主要基于引用计数和标记-清除两种方式。引用计数是指每个对象都有一个引用计数器,每当一个变量引用该对象时,计数器加一;当引用消失时,计数器减一。当计数器为零时,表示该对象不再被引用,垃圾回收器会释放其内存。
然而,引用计数存在循环引用的问题。为了解决这个问题,PHP还采用了标记-清除机制。在标记阶段,垃圾回收器会遍历所有活跃的对象,标记它们为可达。在清除阶段,垃圾回收器会释放所有未被标记为可达的对象所占用的内存。
垃圾回收对性能的影响主要体现在以下几个方面:
1. 引用计数法的开销:引用计数法需要维护每个对象的引用计数器,这会带来一定的性能开销。
2. 标记-清除的开销:标记-清除阶段需要遍历所有活跃的对象,这可能会影响性能。
3. 内存碎片:频繁的垃圾回收可能会导致内存碎片化,影响内存分配效率。
4. 停止-开始(Stop-The-World)问题:在垃圾回收过程中,应用程序可能会暂停执行,这被称为停止-开始问题。
总之,垃圾回收是PHP中一个重要的内存管理机制,它有助于提高程序的性能和稳定性。然而,过度依赖垃圾回收可能会带来一些性能问题。因此,开发者需要根据实际情况合理使用垃圾回收,以达到最佳的性能表现。
本篇文章给大家介绍一下垃圾回收,浅析PHP中垃圾回收机制,最后聊聊垃圾回收对性能的影响,一起开看看吧!相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个变量都会保存在内存中。其实,我们这些开发者就是在来回不停地操纵内存,相应地,我们如果一直增加新的变量,内存就会一直增加,如果没有一个好的机制,那么内存就会无限制地增加最终撑满所有的内存。这就造成了内存泄露。但在日常开发中,除非一次加载一个很大的文件,我们几乎见不到内存超限的错误,这就是垃圾回收机制的作用。
垃圾回收是什么东西?
在使用 C 语言的时候,我们都要手动使用 free 来释放内存,在 C 之后的大部分编程语言都会自带一个垃圾回收之类的处理能力,也就是我们今天要说的垃圾回收机制,也称为 GC 。在有 GC 能力的开发语言中,我们不需要去关心什么时候释放内存,甚至我们完全不需要去了解这一块的内容,因为这些语言在底层已经帮我们处理好了关于内存释放的问题。
当然这方面的内容最出名的就是 Java 中的垃圾回收机制,其实 PHP 也有相应的处理机制,当然,很多 PHPer 可能从来没接触过,今天我们就来探讨一下这方面的内容。
PHP 的垃圾回收算法
在之前的文章中,我们有介绍过引用计数的概念。在 PHP5.3 之前,PHP 的垃圾回收机制非常简单,就是把 refcount 为0的全部清理回收掉,在底层也就是 free 掉了。但是这种方式会带来一个问题,也就是我们在引用计数这篇文章中说过的循环引用,这种引用问题通过普通的判断 refcount 的方式是无法回收的。所以在 PHP5.3 之前,循环引用是会造成内存泄露的。
之所以强调版本,那是因为在 5.3 之后,PHP 改进了垃圾回收的算法,使这种循环引用得到了解决。(当然,我们在日常开发中尽量要避免这种循环引用的问题)。具体算法我们引用官方的图片:
在官方文档中有详尽的解释,不过还是会看得很懵逼。我们就用简单的语言(说人话)来描述这个过程。
首先,我们有个根缓冲区的概念,就是图中的 root 。在底层通过一系列看不懂搞不明白的算法我们能找到每个变量的一个可能根。PHP 会将变量的可能根放入根缓冲区。
当根缓冲区满了的时候,一般这个默认值是10000,需要修改源码重新编译才能修改这个值。PHP 就会启动垃圾回收机制,从根缓冲区中按照深度遍历的算法来查找所有的和这个可能根相关的变量,并将某一个可能根找到的变量的 refcount 减1,并做一个标记当前这个“已减”。
然后再次深度遍历,如果 refcount 不是0的,就加1,如果是0的就保持不变。
接着清除根缓冲区中的所有可能根,清除而不是删除。然后清理释放所有的 refcount 为0的变量内容。
是不是已经懵逼了?其实我也很懵逼,都不知道这段是怎么写下来的....
记住几个要点就可以对付面试并秒杀大部分人了。
- PHP5.3 后并不是直接看每个变量的 refcount 是否为0了
- 使用的算法是深度遍历,有个根缓冲区,根据它来清理,具体算法需要比较扎实的 C 和算法基础,学源码的时候再好好研究吧
- 5.3 之后和算法解决了循环引用的问题
- 内存泄露值会保持在某一个范围,不会出现立即大范围崩溃的情况
垃圾回收对性能的影响
前文说过,垃圾回收在根缓冲区满了之后会马上执行。其中也会进行两次的深度遍历,这就不可避免的带来了性能的消耗。毕竟算法的执行都是需要耗时的。不过相对于内存溢出这种毁灭性的错误来说,垃圾回收带来的性能损耗基本上是可以忽略不计的。
总结
垃圾回收的内容其实我们只需要记住几个关键点就可以了,具体的核心算法和内容是需要在更深入的研究源码后才能完全了解的,当然,这也是我们学习的目标,之后也一定会涉猎源码底层的相关内容,就让我们拭目以待吧!

