”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > PHP:用简单的话解释垃圾收集器

PHP:用简单的话解释垃圾收集器

发布于2024-12-11
浏览:416

垃圾收集器(GC)是 PHP 中的内部内存管理系统,但有一些微妙之处需要理解。

?为什么 GC 会存在?

GC 自动化内存管理,从而消除了通过手动任务处理内存的麻烦(这将是乏味的)。

这使开发人员能够专注于他们的业务逻辑,而不必过度担心“内存不足”错误。

当然,这不是魔法。

?简而言之 10,000 个对象

释放不再需要的对象可以防止内存泄漏

GC 使用计数机制来确定要删除的元素。如果没有引用指向特定对象(即 $counter = 0),则该对象有资格进行清理。

它工作得很好,但一些参考可能有问题:

class A {
    public $b;
}

class B {
    public $a;
}

$a = new A();
$b = new B();

$a->b = $b;
$b->a = $a;

unset($a);
unset($b);

在这种设计不佳的情况下,即使我们取消设置 $a 和 $b,PHP 也不会释放内存,因为它们相互引用,导致 PHP 认为它们仍在使用中。

幸运的是,还有另一种称为循环收集器的机制:

gc_collect_cycles();

粗略地说,收集器遍历所有引用并应用算法来标记正在使用的对象,这会显示要收集的对象(未标记的对象)。

但是,只有达到10,000个具有潜在循环引用的对象的阈值,PHP才会触发自动循环收集。

再次强调,这并不神奇,因此只有在少数情况下才必须调用 gc_collect_cycles()。

?坦斯塔足球俱乐部

糟糕的设计可能导致对象之间的关系过于复杂,从而导致更多的引用和更频繁的垃圾收集。

每个引用计数对象都需要额外的存储空间来存储其引用计数。

来源:维基百科 - 引用计数

与内存清理操作相关的开销会显着影响全局性能,并最终增加特定场景中的执行时间。

10 年前,Composer 仅通过使用 gc_disable() 函数就获得了巨大的性能提升。

来源:Composer - 禁用 GC

确实,PHP 7 极大地改进了 GC,所以它不再是 2014 年的样子了。

此外,PHP 8版本改进了内存分配策略,并添加了更多有关GC操作的有用统计信息,以便更好地监控(8.3中的gc_status())。

大多数PHP应用程序都是请求驱动的,请求结束时内存会自动清除。

再说一遍,这很酷,但并不神奇。异步请求和长期存在的对象/守护进程会发生什么?

您可能在某些时候遇到内存泄漏。

? PHP 的 GC 有何不同?

此时,您可能还看不出 PHP 的 GC 与其他语言有何不同。

大多数时候,其他语言不依赖引用计数来收集垃圾或者可能使用不同的实现。

例如,许多使用跟踪算法,该算法也标记未使用的对象,但不增量操作。这是一个图的遍历。

此外,某些语言不允许这种直接控制(例如,运行时开/关)。

像往常一样,有一些优点和不方便,因此您可能会看到一些混合方法。

?‍?与 PHP 的 GC 交互

您可以利用内置的 gc_* 帮助程序。

例如:

  • gc_collect_cycles 手动触发垃圾收集
  • gc_status() 给出当前状态
  • gc_disable() 禁用它
  • gc_enable() 启用它

这些函数有助于调试或微调垃圾收集必要时

?了解内存错误

您可以阅读这篇文章以获取更多见解:

PHP: The Garbage Collector explained with simple words

PHP:内存错误

spO0q ? ・ 2023 年 5 月 24 日

#php #初学者 #编程

?弱地图可以拯救?

PHP 7.4 引入了弱引用,PHP 8 引入了弱映射。

弱映射可以被描述为弱引用的集合。

此数据结构是一种多功能键值存储,可帮助 PHP 跟踪项目,而不会造成混乱或消耗过多空间。

您可能会将其视为临时存储,当不再需要时将立即清除,因为没有[强]引用可以阻止垃圾收集:

$object = new stdClass;
$map = new WeakMap();
$map[$object] = true;
$object->name = 'some name';
print_r($map);// $object is stored in $map

unset($object);

print_r($map);// $object is cleaned and no longer available

✅ 优点

  • 非常简单
  • 非常适合缓存或记忆(例如,昂贵的计算)

❌ 缺点

  • 虽然键(对象)不会阻止垃圾回收,但值可以,因此术语“任意值”可能会产生误导(仅使用简单数据类型作为值)
  • 有价值的用例是有限的

?优化代码

  • 利用减少相互依赖性的设计模式
  • 使用依赖注入
  • 不要将太大的数据集加载到内存中,并使用集合和生成器而不是巨大的数组
  • 监控内存使用情况
  • 使用指标分析您的代码
  • 谨慎使用 gc_enable()、gc_disable() 和 gc_collect_cycles()

包起来

对于大多数用法,您不必担心内存管理,因为 PHP 已经处理了它。

但是,由于现代堆栈使用长寿命对象,因此您需要监视应用程序是否存在潜在的内存泄漏。

如果遇到问题,您可能需要优化代码和/或直接与 GC 交互。

版本声明 本文转载于:https://dev.to/spo0q/php-the-garbage-collector-explained-with-simple-words-1b7d?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何简化PHP中的JSON解析以获取多维阵列?
    如何简化PHP中的JSON解析以获取多维阵列?
    php 试图在PHP中解析JSON数据的JSON可能具有挑战性,尤其是在处理多维数组时。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    编程 发布于2025-04-11
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在Java中的多个返回类型:一种误解类型:在Java编程中揭示,在Java编程中,Peculiar方法签名可能会出现,可能会出现,使开发人员陷入困境,使开发人员陷入困境。 getResult(string s); ,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但这确实是如此吗...
    编程 发布于2025-04-11
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-04-11
  • 如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解决方案: args)抛出异常{ 日历cal = calendar.getInstance(); SimpleDateFormat SDF =新的SimpleDateFormat(“...
    编程 发布于2025-04-11
  • 如何使用替换指令在GO MOD中解析模块路径差异?
    如何使用替换指令在GO MOD中解析模块路径差异?
    在使用GO MOD时,在GO MOD 中克服模块路径差异时,可能会遇到冲突,其中3个Party Package将另一个PAXPANCE带有导入式套件之间的另一个软件包,并在导入式套件之间导入另一个软件包。如回声消息所证明的那样: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    编程 发布于2025-04-11
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-11
  • 如何在php中使用卷发发送原始帖子请求?
    如何在php中使用卷发发送原始帖子请求?
    如何使用php 然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头的数组使用curlopt_httpheader选项:响应将存储在变量$ result。示例代码...
    编程 发布于2025-04-11
  • 对象拟合:IE和Edge中的封面失败,如何修复?
    对象拟合:IE和Edge中的封面失败,如何修复?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    编程 发布于2025-04-11
  • 如何有效地选择熊猫数据框中的列?
    如何有效地选择熊猫数据框中的列?
    在处理数据操作任务时,在Pandas DataFrames 中选择列时,选择特定列的必要条件是必要的。在Pandas中,选择列的各种选项。选项1:使用列名 如果已知列索引,请使用ILOC函数选择它们。请注意,python索引基于零。 df1 = df.iloc [:,0:2]#使用索引0和1 c...
    编程 发布于2025-04-11
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-04-11
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-04-11
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-04-11
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本编号的替代方法,它是使用以下语法:获取最新版本:未压缩)While these legacy URLs still remain in use, it is recommended ...
    编程 发布于2025-04-11
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-04-11
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-04-11

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3