当前位置: 首页 > news >正文

PHP 8.5 垃圾回收改进

PHP 8.5 垃圾回收改进

PHP 内存消耗的大幅优化已经很罕见了。近年来的内存改进范围较小,主要集中在某些类型变量的细节上。

比如改进垃圾回收器(GC)在边缘情况下的表现。Iljia Tovilo 为 PHP 8.5 贡献了这个优化,标题是“将枚举和静态伪闭包标记为不可回收”。

简单来说,对于这两种变量类型,循环回收器不会尝试“收集”它们,大量使用这些实例时就能避免不必要的 GC 运行。

这没有任何副作用,因为这些类型本身不可能形成循环引用,本来就不在 GC 的管辖范围内。

原文链接 PHP 8.5 垃圾回收改进

快速回顾:PHP 的垃圾回收器是如何工作的?

要理解为什么这很有用,先快速回顾一下 PHP 垃圾回收的工作原理。

简单来说,PHP 的 GC 不是持续运行的,而是由阈值触发。这个阈值是:内存中至少有 10,000 个可能存在循环引用的对象或数组。如果这些实例数量不断增加而无法清理,GC 可能会在越来越多的对象上运行,消耗宝贵的计算资源。

因此,减少符合垃圾回收条件的对象数量可以降低 GC 运行的概率,从而提升性能。

PHP 7.3 添加了一个实用函数 gc_status()(文档),可以很方便地了解垃圾回收的性能情况。

实际收益是什么?

看一下 PR 中的例子,大量 first class callable 实例被添加到数组中,然后进行迭代。

<?phpfunction foo() {}$array = [];
for ($i = 0; $i < 10_000_000; $i++) {$array[] = foo(...);
}//
// 这个循环是为了确保触发循环回收器:
// - `as $foo` 会增加数组元素的引用计数
// - 变量超出作用域后引用计数又会减少
//
foreach ($array as $foo) {}echo json_encode(gc_status(), JSON_PRETTY_PRINT);

在旧版 PHP 中,这会触发循环回收器检查所有这些实例是否存在循环引用。由于这些实例不可能有循环引用,这些检查是多余的。对于 1000 万个条目,这导致了 44 次 GC 运行,而 PHP 8.5 及以后版本在相同代码下是 0 次。

定义:"静态伪闭包"

PR 标题说优化适用于“枚举和静态伪闭包”。静态伪闭包显然是更常见的情况,而且术语与用户层面的命名不一致,我们来深入了解一下:什么是“静态伪闭包”?

上面的例子使用了"静态伪闭包",在用户层面通常称为"first-class callable"。在这个例子中,就是 foo(...)

要判断一个 callable 是否是"伪闭包",可以检查该 callable 的反射类的 anonymous 标志是否返回 false,即 (new \ReflectionFunction($callable))->isAnonymous();

类型中的“静态”部分指的是 OOP 中的 static:没有访问对象实例(即 $this)的权限。

在下面这个不同闭包的列表中,你可以看到哪些被 PR 认为是静态伪闭包,哪些不是:

<?phpclass Foo 
{public static function bar(): void {}public function baz(): void {}    
}function bar(): void {}//
// 静态伪闭包
//
var_dump(...);
bar(...);
Foo::bar(...);
$callable = Closure::fromCallable('bar');
$callable(...);// 伪闭包,但非静态
(new Foo())->baz(...);
// 匿名函数,不是伪闭包
$anon = static function () {};
$anon(...);

枚举的情况

第二种被优化的类型是枚举实例。这在实际项目中的影响可能较小,因为只有当代码库包含大量枚举且每个枚举有很多 case 时才会影响性能。枚举实例是单例的,每个枚举 case 只会被实例化一次。即使有数千个引用指向相同的三四个枚举 case,也不会有影响,因为每个枚举 case 在 GC 的根缓冲区中只能出现一次。

总结

这样的小改进表明,PHP 的内存管理在已经相当成熟的情况下仍然可以继续优化。

这个改动可能在某些情况下提升性能,但更重要的是,它确保垃圾回收运行不会在无关的检查上浪费时间。

感谢 Iljia Tovilo 的贡献。

http://www.jsqmd.com/news/81312/

相关文章:

  • 2025年评价高的玻璃门液压合页/阻尼缓冲液压合页最新品牌厂商榜(更新版) - 行业平台推荐
  • 架构革命:FlatBuffers与gRPC如何重塑微服务通信新范式
  • 多摄像头实时物体追踪与计数系统:如何实现智能安防监控?
  • 喵喵喵 XII
  • 3大核心场景深度解析:用Dify工作流构建企业级智能应用
  • 显存减半速度翻倍:LightVAE如何优化AI视频生成效率?
  • VirtualMotionCapture虚拟动作捕捉终极指南:从入门到精通
  • Fast-Android-Networking网络拦截器:快速构建高效网络层的终极指南
  • 提升Neovim开发效率:bufferline.nvim终极配置指南
  • Lottie-web:打破网页动画开发壁垒的革命性方案
  • 2025年中国高品质防伪标签加工厂推荐:哪家专业、服务优? - myqiye
  • 2025年调度中心控制台厂五大推荐:看哪家技术实力强? - 工业推荐榜
  • SD卡位置不可用/移动硬盘磁盘结构损坏/优盘参数错误数据恢复 - 工业品牌热点
  • 2025年热门的酒店工程暗藏合页优质厂商精选榜(口碑优) - 行业平台推荐
  • 字节跳动BFS-Prover-V2突破95%数学推理准确率,重新定义AI定理证明边界
  • AWS-Nuke终极指南:如何快速彻底清理AWS云环境资源
  • MIT:LLM强化学习推测个性化需求
  • THUDM模型2025年AI选型实战指南:三大应用场景深度解析
  • novelWriter终极入门指南:从零开始掌握小说写作神器
  • 5步掌握prompt优化器:Vue3 + TypeScript架构深度解析
  • OTPAuth:构建坚不可摧的账户安全防线
  • Readr数据读取终极指南:快速上手R语言数据处理神器
  • Smith Setup V4.1.0.0:终极电子电路设计与阻抗匹配工具
  • Snap.Hutao原神工具箱终极使用指南:从新手到高手的快速成长路径
  • Laravel 使用 PDO 作为底层数据库驱动的庖丁解牛
  • libpag动画渲染技术:跨平台AE特效的工程化解决方案
  • SSDTTime终极指南:告别繁琐的黑苹果DSDT手动配置
  • ImageKnife终极实战手册:从入门到精通的高性能图片加载方案
  • KataGo围棋AI终极GUI选择指南:如何快速配置最佳界面
  • 终极指南:如何用Charticulator创建自定义数据可视化图表