PHP垃圾收集和内存优化
我正在做一些PHP内存基准测试,我想知道是否有一种方法可以优化垃圾收集器以减少内存消耗(在JAVA等其他语言中也是如此) 我在php.ini中只找到了三个与GC相关的可定制参数:PHP垃圾收集和内存优化,php,memory,memory-management,benchmarking,Php,Memory,Memory Management,Benchmarking,我正在做一些PHP内存基准测试,我想知道是否有一种方法可以优化垃圾收集器以减少内存消耗(在JAVA等其他语言中也是如此) 我在php.ini中只找到了三个与GC相关的可定制参数:session.GC\u probability、session.GC\u divisior和session.GC\u maxlifest。这只是针对课程,我并没有对此进行基准测试 到目前为止,我知道可能的优化与代码相关,例如避免循环引用,通过调用gc\u collect\u cycles()(感谢本文)强制执行垃圾收集
session.GC\u probability
、session.GC\u divisior
和session.GC\u maxlifest
。这只是针对课程,我并没有对此进行基准测试
到目前为止,我知道可能的优化与代码相关,例如避免循环引用,通过调用gc\u collect\u cycles()
(感谢本文)强制执行垃圾收集循环
有人知道PHP内存管理中的配置技巧或良好实践吗?我在不再需要变量时使用unset()方法清除变量。据我所知,使用
gc\u collect\u cycles()强制收集是最接近于在时间t时最小化内存使用的方法
GC当然是一个有时间限制的操作,应用程序很少受到严重的内存限制,因此,在整个程序执行过程中提供不必要地触发GC运行的选项是没有意义的。按照这种思路,PHP确实提供了按需打开和关闭循环收集器的功能(gc_enable()
,gc_disable()
),这样您就可以根据时间优化代码(避免gc决定启动的开销)——当然,很容易看出这是多么有用
一般来说,哲学上的PHP避免了诸如内存管理和GC之类的主题,您的基准测试也许应该尊重这一点,以获得更真实的前景
希望这有帮助
(对@GordonM引用微观优化的评论表示赞同。)一般来说,PHPs内存管理对于您声明和使用的所有变量都是开箱即用的。使用refcounting这个概念,PHP可以查看变量是否不再使用,然后自动清除它
垃圾收集器仅在对象具有循环引用的情况下才有意义,A指向B,B指向A。在这种情况下,引用计数不起作用
如果PHP内存中正好有10.000个对象是潜在循环的,可能不再使用,那么PHP垃圾收集器将在启用时触发,默认情况下是启用的。您可以在运行时使用gc\u enable()
和gc\u disable()
禁用或启用它
您还可以调用gc\u collect\u cycles()
手动清理这些对象
但是如果需要,如何优化这个过程呢?运行cycle collector不一定是高效或有用的,从10000个潜在对象来看,其中许多对象可能仍在使用中,无法清理。在这种情况下,检查所有对象并决定不清理它们是在浪费CPU周期。如果这样做,内存将不会减少
通常GC只在长时间运行的脚本中触发,只有在短时间的web请求中才会在创建太多对象时触发。一般来说,您不应该考虑太多,因为默认值适用于99%的用例
通过“垃圾统计”PHP扩展,您可以访问有关GC运行效率和速度以及内存减少量的指标和统计数据。它在PHP7+上工作(因为从那时起钩子才可用):
如果已安装扩展,则可以通过调用以下命令来查看CLI脚本的垃圾收集统计信息:
$ php -dgc_stats.enable=1 -dgc_stats.show_report=1 test.php
Found 7 garbage collection runs in current script.
Collected | Efficency% | Duration | Memory Before | Memory After | Reduction% | Function
----------|------------|----------|---------------|--------------|------------|---------
0 | 0.00 % | 0.01 ms | 365824 | 366320 | -0.14 % | gc_collect_cycles
10000 | 100.00 % | 2.75 ms | 4651320 | 491816 | 89.43 % | foo
10000 | 100.00 % | 3.54 ms | 4652784 | 493280 | 89.40 % | foo
10000 | 100.00 % | 2.11 ms | 4654248 | 494744 | 89.37 % | foo
10000 | 100.00 % | 3.26 ms | 4656168 | 496664 | 89.33 % | Test::foo
9000 | 90.00 % | 1.51 ms | 4694680 | 951176 | 79.74 % | Test::foo
10000 | 100.00 % | 3.11 ms | 5112272 | 952768 | 81.36 % | Test::foo
从web(例如Apache或FPM)请求中,可以使用函数$runs=gc_stats()
访问此信息并将其写入日志文件
根据这些信息,您可以做出唯一可以优化的决定:根据脚本的运行效率,在脚本中启用或禁用GC。通过配置指令,您没有什么可以做的,只有以这样一种方式编写代码,以减少内存使用量,这对大多数人来说本身就是一种误解“程序员”在那里:)除非你真的遇到了由于GC问题导致的内存消耗和/或性能问题,否则我真的不会担心,因为这在很大程度上是一个问题。事实是,我正在搜索这种GC微优化。但是,显然PHP垃圾收集器无法优化。我想确定一下。谢谢。