首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在对变量执行某些操作之后,将变量赋值给自己有什么区别吗?还是给另一个变量分配变量?

在对变量执行某些操作之后,将变量赋值给自己有什么区别吗?还是给另一个变量分配变量?
EN

Stack Overflow用户
提问于 2012-12-29 10:46:32
回答 1查看 532关注 0票数 2

不久前,在对赋值变量进行了一些操作之后,我对它们本身进行了一次辩论。

将变量赋值给自己,AI

代码语言:javascript
复制
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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-04 07:17:38

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

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

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

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

代码语言:javascript
复制
$explodedString = explode(",", $repeatedString);
unset($repeatedString); // or $repeatedString = false;

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

更新:

因为PHP使用引用计数来进行正常的内存管理,所以AI应该立即收回字符串使用的内存。该字符串以1的引用计数开始,当它被传递给explode()时,重新计数将增加到2(用于count参数变量的引用)。当explode()返回时,参数变量的作用域结束,refcount返回到1。然后,当分配给$repeatedString时,重算下降到0,字符串的内存被回收。

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

代码语言:javascript
复制
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";

结果:

代码语言:javascript
复制
Begin: 226088
After allocate: 286640
After unset: 286552
After GC: 226088

有关详细信息,请参阅PHP垃圾收集文档

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14080902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档