我运行下面的代码而不取消设置数组,然后使用PHP取消设置数组
未设置($阵列这里)
当我使用unset时,内存数量会增加。有什么想法吗?更好的是,释放内存的正确方法是什么?
注意:请不要讲述预优化,EVIL等等,这是一个测试,所以请不要讲它,谢谢。
//show current memory usage BEFORE
echo memory_get_usage() . "\n"; // 57960
//start timer
$start3 = microtime(true);
// arrays for header menu selector
$header_home = array('home' => true);
$header_users = array('users.online' => true, 'users.location' => true, 'users.featured' => true, 'users.new' => true, 'users.browse' => true, 'users.search' => true, 'users.staff' => true);
$header_forum = array('forum' => true);
$header_more = array('widgets' => true, 'news' => true, 'promote' => true, 'development' => true, 'bookmarks' => true, 'about' => true);
$header_money = array('account.money' => true, 'account.store' => true, 'account.lottery' => true, 'users.top.money' => true);
$header_account = array('account' => true);
$header_mail = array('mail.inbox' => true, 'mail.sentbox' => true, 'mail.trash' => true, 'bulletins.post' => true, 'bulletins.my' => true, 'bulletins' => true);
//run throught 1,000 iterations
for($i = 0; $i < $iterations; ++$i) {
if(isset($header_home[$p]))
$current_home = 'current';
else if(isset($header_users[$p]))
$current_users = 'current';
else if(isset($header_forum[$p]))
$current_forum = 'current';
else if(isset($header_more[$p]))
$current_more = 'current';
else if(isset($header_money[$p]))
$current_money = 'current';
else if(isset($header_account[$p]))
$current_account = 'current';
else if(isset($header_mail[$p]))
$current_mail = 'current';
}
//unset the arrays
unset($header_money);
unset($current_home);
unset($current_users);
unset($current_forum);
unset($current_more);
unset($current_account);
unset($current_mail);
//show time
$end3 = microtime(true);
echo number_format($end3 - $start3, 7) . ' Time3 ARRAY<br />';
//show current memory usage AFTER
echo memory_get_usage() . "\n";
答案 0 :(得分:10)
在这样做之后我做了一个非常快速的测试:
$iterations = 10;
$p
而非$i
(您使用$p
访问数组元素,而不是$i
) < / LI>
我得到了这个,使用PHP 5.3.1 (今天的快照):
328616
332176
331728
三个输出是:
for
循环因此,unsets实际上会激发一些内存的释放,而不是增加使用的内存; - )
但是只释放了分配内存的很小一部分......
现在,问题可能是“是什么导致一些内存被使用而没有被释放,如果我在数组上调用unset就会发生事件” - 实际上,这可能是你最初的意思?
好吧,我想不安排数组本身不会强制PHP释放为数组内部的项目分配的内存...
赞this note on the unset manual page says(引用):
unset()正如它的名字所说的那样 - 取消设置变量。它不会强制立即释放内存。 PHP的 垃圾收集器会在它做的时候做 尽快看到拟合 - 意图 无论如何都不需要那些CPU周期, 或者直到剧本之前 无论发生什么,都会耗尽内存 第一
如果你正在做$ whatever = null; 然后你正在重写变量 数据。你可能会释放内存/ 缩小速度,但它可能会窃取CPU 从真正需要的代码循环 它们越早,导致时间越长 总体执行时间。
实际上,这可能看起来很有趣; - )
尽管如此,进行几次快速测试并没有得到任何有趣的东西;我想我的脚本/数据不够大,不能强制PHP释放未使用的内存,或类似的东西......
注意:如果我使用gc_collect_cycles
(PHP&gt; = 5.3)在取消设置后强制进行垃圾回收,它不会改变任何东西 - 我想这是因为没有“失去了周期“。
* BTW:运行你的代码给了我很多通知(例如$ p vs $ i);你是否将error_reporting设置为报告通知? *
答案 1 :(得分:3)
在数组存在之前,您第一次调用memory_get_usage()
。您应该在阵列的创建+填充和unset()
的
在这里你看到的只是在脚本末尾使用的内存比在开头时使用的更多。
答案 2 :(得分:1)
unset()
不是“强制垃圾收集”机制。
因此调用unset()
并不意味着变量持有的内存立即可用,它只是意味着变量被安排用于垃圾收集。 PHP引擎按照自己的计划执行此操作。
答案 3 :(得分:1)
我不知道这是否有所不同,但您没有取消设置$start3
,$end3
以及除$home_xxx
以外的所有其他$home_money
数组。
另外我建议保持基准更简单。比如只使用一个数组。
保持简单。它将使您的测试/基准更有意义。
修改强>:
只是玩了一下......
首次测试
<?php
$array = array();
echo "START:". memory_get_usage() . "\n";
for ( $i = 0; $i<1000; $i++ ) {
$array[] = 'foo';
}
echo "BEFORE UNSET: " . memory_get_usage() . "\n";
unset($array);
echo "AFTER UNSET: " . memory_get_usage() . "\n";
sleep(120);
echo "AFTER A WHILE: " . memory_get_usage() . "\n";
输出:
START:53632
BEFORE UNSET: 146360
AFTER UNSET: 118848
AFTER A WHILE: 118848
第二次测试:
<?php
$array = array();
echo "START:". memory_get_usage() . "\n";
for ( $i = 0; $i<1000; $i++ ) {
$array[] = 'foo';
}
echo "BEFORE UNSET: " . memory_get_usage() . "\n";
for ( $i = 0; $i<count($array); $i++ ) {
unset($array[$i]);
}
unset($array);
echo "AFTER UNSET: " . memory_get_usage() . "\n";
输出:
START:53944
BEFORE UNSET: 146680
AFTER UNSET: 119128
因此,仅设置垃圾收集计划的理论并不成立(至少在PHP 5.2.8中没有,但在PHP 5.3的GC中它们再次发生了很大变化)。
我担心你没有比未设置更多的东西: - (