取消设置数组后PHP内存使用量会增加吗?

时间:2009-08-21 15:41:38

标签: php

我运行下面的代码而不取消设置数组,然后使用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";

4 个答案:

答案 0 :(得分:10)

在这样做之后我做了一个非常快速的测试:

  • 在脚本开头声明$iterations = 10;
  • 在for循环中使用$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中它们再次发生了很大变化)。

我担心你没有比未设置更多的东西: - (