从一个随机的php.net帖子:
如果你正在做$ whatever = null; 那么你正在重写变量的数据.您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取CPU周期,从而导致更长的总体执行时间.
显然这是无可争议的事实,所以也许有人会如此善良地解释.
我的意思是,什么,unset神奇地没有执行任何汇编指令,$whatever = null;而是?如上所述,答案和说法一样有用
$ whatever = null重置缓冲区和L1缓存,而unset清除缓冲区并重置L2缓存.
Techno mumbo jumbo并不构成答案.
我对PHP有点新,我想知道:
在PHP中取消设置变量有多重要?
我知道在像C这样的语言中,我们释放分配的内存以防止泄漏等.通过在完成变量时使用unset变量,这会显着提高我的应用程序的性能吗?
此外,是否存在比较使用未设置和不使用未设置之间的差异的基准?
在PHP中取消设置变量是否有真正的好处?
class test {
public function m1($a, $b)
$c = $a + $b;
unset($a, $b);
return $c;
}
}
Run Code Online (Sandbox Code Playgroud)
在运行时期间,未设置的变量实际上是否会降低内存消耗,这是真的吗?
我的PHP应用程序有一个可以导入记录的导入脚本.
目前,它是从CSV文件导入的.它正在读取CSV文件的每一行,使用fgetcsv一次一行,并且对于每一行,它在该记录上进行大量处理,包括数据库查询,然后继续下一行.它不应该继续累积更多的内存.
在导入大约2500条记录之后,PHP死了,说它已超过其内存限制(132 MB左右).
CSV文件本身只有几个megs - 发生的其他处理会进行大量的字符串比较,差异等.我有大量的代码在运行它并且很难想出一个'最小的再现样品'.
找到并解决这个问题有哪些好方法?
发现问题的原因
我有一个调试类,它在运行时记录我的所有数据库查询.因此,那些长约30KB的SQL字符串留在内存中.我意识到这不适合设计为长时间运行的脚本.
可能还有其他内存泄漏源,但我很确定这是我的问题的原因.
我有一个大的xlsx文件正在90MB使用phpexcel它给我
Warning: simplexml_load_string(): Memory allocation failed : growing buffer
Run Code Online (Sandbox Code Playgroud)
我尝试使用此处记录的每个方法加载文件,并且还更改了php.ini memory_limit = -1.
我正在尝试将xlsx文件转换为csv文件,以便可以轻松加载.
有没有办法在不使用phpexcel的情况下将xlsx文件转换为csv?
在维护代码时,我遇到了循环,在循环结束时,几个变量被设置为NULL如下:$var = NULL;.根据我在手册中的理解,NULL主要用于在PHP代码中进行比较.由于NULL没有类型而且不是字符串或数字,输出它是没有意义的.
遗憾的是我无法提供示例,但我认为NULL值正在写入我们代码中的文件.我的问题是:$var在赋值后是否有值,并将回显/写入它产生输出?
编辑: 我已阅读PHP手册条目 NULL.没有必要在评论或回答中发布这个:http://php.net/manual/en/language.types.null.php,或者在没有RTM的情况下向我推荐.谢谢!
这个问题是对使用PHP释放内存有什么好处的后续问题:unset()或$ var = null
长话短说,我自己的基准似乎与该问题中给出的答案相矛盾.我的问题是......为什么?答案是错的还是有些东西我只是不理解?
<?php
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
$a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
$a = 'a';
unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
?>
Run Code Online (Sandbox Code Playgroud)
看来,"= null"似乎更快.
PHP 5.4结果:
PHP 5.3结果:
PHP …
我经常发现在解释PHP unset()不会立即触发"垃圾收集" 时使用以下引用的引用,但仅在它看起来合适时(强调我的):
unset()正如它的名字所说 - 取消设置一个变量.它不会强制立即释放内存.PHP的垃圾收集器会在看到拟合时执行它 - 尽快意图,因为无论如何都不需要那些CPU周期,或者在脚本 耗尽内存之前,无论先发生什么.
如果你正在做$ whatever = null; 那么你正在重写变量的数据.您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取CPU周期,从而导致更长的总体执行时间.
我想知道这个"低内存"和"自由CPU周期"触发垃圾收集的C代码是如何工作的,以及它是否在PHP 5.2.x和PHP 5.3+之间有所不同.
所以我下载了PHP 5.2.17的C源文件,并试图找到正确的代码部分.也许我只是失明,或者我的C技能太低,但我找不到这样的代码.
有人能指出我正确的C文件吗?
编辑:
在搜索上述引用的示例时,我意识到一些奇怪的东西.
一些示例,如/sf/answers/40948771/,通过使用以下URL对php.net上的注释引用此引用:http://us2.php.net/manual/en /function.unset.php#86347.
浏览此URL仅显示unset()手册的顶部.评论#86347缺少.
检查返回机器显示,该评论DID存在于2008年10月,但在2012年9月或之后的某个时间消失(原因未知).
也许这句话是,而且一直都是,这是完全错的?
或者有谁在那里,谁能指出我正确的C文件?
您可以在下方看到两个简化的摘要,其结果不会发生变化.
模式1,从头开始的对象:
foreach ($recipients as $recipient) {
$message = new Message();
$message->setBody("This is the body of the message.");
$message->setRecipient($recipient);
$transport->sendMessage($message);
$persister->saveToDatabase($message); // Updated line
unset($message);
}
Run Code Online (Sandbox Code Playgroud)
模式2,克隆原型对象:
$prototype = new Message();
$prototype->setBody("This is the body of the message.");
foreach ($recipients as $recipient) {
$message = clone $prototype;
$message->setRecipient($recipient);
$transport->sendMessage($message);
$persister->saveToDatabase($message); // Updated line
unset($message);
}
unset($prototype);
Run Code Online (Sandbox Code Playgroud)
在内存使用,垃圾收集和/或CPU周期方面,对象克隆(模式2)是否提供了从头开始创建对象(模式1)的性能改进?还要考虑大量固定属性(在实例之间不会更改)和大量循环.
更新:我需要在每个循环中使用不同的对象实例.我添加saveToDatabase了对示例的调用以使其类似,例如,让它为消息提供ID.;)
前言:我确实知道'unset'在userland中是如何工作的,但我想知道它是如何在内部工作的.
当在zval结构上调用unset时,它会减少引用计数器(refcount__gc).当refcount__gc达到0时,该变量不再使用,可以删除.问题是它是否总是立即完成,或者在某些情况下它可以在以后由垃圾收集器完成?
我发现了两个相互矛盾的陈述:
unset()正如它的名字所说 - 取消设置一个变量.它不会强制立即释放内存.PHP的垃圾收集器会在看到拟合时执行它 - 尽快意图,因为无论如何都不需要那些CPU周期,或者在脚本耗尽内存之前,无论先发生什么.- Stackoverflow回答提到2009 php.net文档
相反的是:
当refcount达到零时,zval被销毁,它所持有的任何内存现在都是免费的 - 更好地理解PHP的垃圾收集,2012年文章
那么哪一个是正确的,比如PHP 5.3和PHP 5.5?如果可能,也许您可以提供PHP源代码中未设置定义的链接.谢谢!