php - 在对其执行某些操作后将变量分配给自身或分配给另一个变量有什么区别吗?

标签 php memory memory-management

不久前,在对变量进行一些操作后,我对将变量赋值给自身进行了争论。

将变量分配给自身[AI]:

echo memory_get_usage() . "\n"; // 645680
$repeatedString = str_repeat('Hello,', 10000);
echo memory_get_usage() . "\n"; // 705944, AI_delta1 = 60264
$repeatedString = explode(',', $repeatedString);
echo memory_get_usage() . "\n"; // 3337888, AI_delta2 = 2631944
echo memory_get_peak_usage() . "\n"; // AI_peak = 3401024

将变量分配给另一个变量 [AAV]:

echo memory_get_usage() . "\n"; // 645752
$repeatedString = str_repeat('Hello,', 10000);
echo memory_get_usage() . "\n"; // 706024, AAV_delta1 = 60272
$explodedString = explode(',', $repeatedString);
echo memory_get_usage() . "\n"; // 3398256, AAV_delta2 = 2692232
echo memory_get_peak_usage() . "\n"; // AAV_peak = 3400984

我创建了两种情况下的内存使用情况测试并减去值:

AAV_delta1 - AI_delta = 8
AAV_delta2 - AI_delta2 = 60288
AAV_peak - AI_peak = -40

根据此结果,使用哪种方法并不重要,内存使用情况 - 相同。这只是一个问题,我是否应该在下面的代码中使用变量 $repeatedString

我的结论是正确的还是我的测试不正确?

为什么会这样?

还有一个问题:AAV_delta1 - AI_delta = 8,我预计它应该等于0。为什么它等于8?

注意:内存使用情况可能因系统而异。

PHP 版本:5.3.5-1ubuntu7.11。

最佳答案

在 AAV 中,有两个数据副本,因为每个变量都必须保留其数据。它们都必须持续存在,直到它们各自的变量被重新分配或超出范围。

在人工智能中,暂时有两个数据副本。一旦分配发生,就不再需要原始值。但是,它使用的内存在垃圾回收发生之前不会被回收。

如果您在分配后立即检查内存使用情况,您将不会注意到差异,因为可能还没有 GC。如果强制执行 GC,您应该会看到 AI 使用的内存比 AAV 少。

您还可以通过在赋值后取消设置原始变量(将此称为AAVU)来在 AAV 中获得相同的内存使用改进:

$explodedString = explode(",", $repeatedString);
unset($repeatedString); // or $repeatedString = false;

与 AI 一样,您必须强制 GC 立即注意到内存使用量的减少。

更新:

由于 PHP 使用引用计数进行正常的内存管理,AI 应立即回收字符串使用的内存。该字符串以引用计数 1 开始。当它被传递给 explode() 时,引用计数增加到 2(对于explode 参数变量的引用)。当 explode() 返回时,参数变量的作用域结束,引用计数返回到 1。然后,当对 $repeatedString 进行赋值时,引用计数下降到 0,字符串的内存被回收。

gc_collect_cycles() 只需要回收作为循环一部分的数组和对象使用的内存。要查看其影响,请尝试以下代码:

gc_enable();
echo "Begin: " .  memory_get_usage() . "\n";
$array = array(str_repeat('Hello,', 10000));
$array[] =& $array; // Create circular reference
echo "After allocate: " . memory_get_usage() . "\n";
unset($array);
echo "After unset: " . memory_get_usage() . "\n";
gc_collect_cycles();
echo "After GC: " . memory_get_usage() . "\n";

结果:

Begin: 226088
After allocate: 286640
After unset: 286552
After GC: 226088

详情参见 PHP Garbage Collection documentation

关于php - 在对其执行某些操作后将变量分配给自身或分配给另一个变量有什么区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14080902/

相关文章:

php - 表单上的单独提交按钮告诉表单 "action"发布到不同的文件?

.net - 在 .NET Web 服务中保存数据的最佳方式

arrays - MIPS 钻石分选

c - 如何仅使用标准库分配对齐的内存?

ios - CGDataProviderCopyData 在内存中累积导致崩溃

php - sonata admin 变量 "form_helper"不存在。 Twig 更新后

php - 每 2 项不同的 html 类

php - 如何在 PHP 中查找对象使用的内存? (大小)

c - 在多台计算机之间共享内存?

php - 如何使用VSCode远程编辑网站文件?