【问题标题】:PHP Object Creation and Memory UsagePHP 对象创建和内存使用
【发布时间】:2010-10-02 22:24:36
【问题描述】:

一个基本的虚拟类:

class foo
{
    var $bar = 0;
    function foo() {}
    function boo() {}
}
echo memory_get_usage();
echo "\n";
$foo = new foo();
echo memory_get_usage();
echo "\n";
unset($foo);
echo memory_get_usage();
echo "\n";
$foo = null; 
echo memory_get_usage();
echo "\n";

输出:

$ php test.php
353672
353792
353792
353792

现在,我知道 PHP 文档说在需要内存之前不会释放内存(达到上限)。然而,我把它写成一个小测试,因为我有一个更长的任务,使用一个更大的对象,以及该对象的许多实例。内存只会攀升,最终耗尽并停止执行。即使这些大对象确实占用了内存,因为我在完成每个(串行)之后销毁它们,它不应该耗尽内存(除非单个对象耗尽了整个内存空间,情况并非如此)。

想法?

【问题讨论】:

    标签: php object memory


    【解决方案1】:

    这是一个带有循环引用的修改示例:

    <?php
    class foo
    {
        public $bar = 0;
        function foo(){}
        function boo(){}
    }
    
    echo memory_get_usage() . "\n";
    
    $foo = new foo();
    unset($foo);
    
    echo memory_get_usage() . "\n";
    
    $arr = array(new foo());
    
    for ($i = 1; $i < 1000000; $i += 2)
    {
        $arr[$i] = new foo();
        $arr[$i - 1] = new foo();
        unset($arr[$i], $arr[$i - 1]);
    }
    
    echo memory_get_usage() . "\n";
    
    for ($i = 1; $i < 1000000; $i += 2)
    {
        $arr[$i] = new foo();
        $arr[$i - 1] = new foo();
        $arr[$i]->bar = $arr[$i-1];
        $arr[$i-1]->bar = $arr[$i];
        unset($arr[$i], $arr[$i - 1]);
    }
    
    echo memory_get_usage() . "\n";
    

    PHP 5.3.6 (cli) 的输出:

    644392
    644392
    644848
    1628592
    

    【讨论】:

      【解决方案2】:

      PHP 对对象和类的支持在 5.2 版中不是很有效(过去也不是这样),但即将到来的 5.3 和 6.0 对类和对象的使用进行了重大改革,您会看到速度和两者的内存都得到了改善。

      我还在 PHP 5.2.x 中编写了一些基本框架,发现内存使用量也令人惊讶地膨胀。尽管考虑到强大的多核 CPU 和内存是多么便宜,但我想说的是,继续以对您最有意义的方式进行编码,并创建更 RAD 设置。

      如果使用 Smarty 或 Drupal 可以让您的工作项目更快地完成,那么请使用它们,或者您做任何自定义的东西。不要让今天糟糕的内存/速度使用让您对 OOP 或框架感到厌烦,因为明天的版本有一些值得注意的改进(现实世界的基准测试显示相同代码的速度提高了 30%)。

      PS:你的设置有问题,我在 Windows XP 上的 Apache /w PHP 5.2.8 上运行了相同的代码,得到:60872 61080 61080 61080

      【讨论】:

      • 你是说硬件可以解决这个问题吗?我有完全相同的问题,内存不断攀升直到脚本崩溃,而 CPU 一直处于 100%(双核 3.06 Ghz 英特尔,8 Gigs Ram)。我考虑过用硬件来解决我的问题。四核能否将执行速度提高一倍? Hex 核心会翻两番吗? (假设每个场景的 RAM 量相同)
      • 当您遇到内存使用率上升的情况时,则存在未清理的错误或泄漏。您必须深入研究才能找到任何帮助,但 95% 的人处理这个问题的方式是重新启动脚本/会话/网络服务器/服务器。缓慢的内存使用是服务器设置中大多数速度变慢和不稳定的原因,有时除了运行您的网络服务器、PHP、MySQL 等的最新副本并希望该错误存在并已修复之外,没有任何修复。跨度>
      【解决方案3】:

      您是否有任何循环引用可以阻止垃圾收集器执行其任务?

      我进行了快速测试,创建了 1,000,000 个对象,但内存没有被耗尽:

      class foo
      {
          var $bar = 0;
          function foo() {}
          function boo() {}
      }
      
      echo memory_get_usage() . "\n";
      
      $foo = new foo();
      unset($foo);
      
      echo memory_get_usage() . "\n";
      
      for ($i = 0; $i < 1000000; $i++)
      {
          $var = 'foo' . $i; // Use a different variable name each time
          $$var = new foo();
          unset($$var);
      }
      
      echo memory_get_usage() . "\n";
      

      65080 65384 65568

      【讨论】:

      • 在 Windows 上的 5.2.8 上,我得到了 62360 62528 62712,它甚至更小:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 2011-01-04
      • 1970-01-01
      • 2012-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多