如何(如果可能的话)在这个PHP示例中优化内存

时间:2014-09-20 14:11:36

标签: php oop memory-management php-internals

我试图理解PHP在这两个例子中如何处理内存消耗。

示例:1

   // foo.php
    class foo{
        public function __construct()
        {
          $a = new PDO(...);
          $b = new StdClass; 
          $c = new Reflection; 
          $d = new SessionHandler; 
        }

        public function w(){}
        public function x(){}
        public function y(){}
        public function z(){}
     }

示例:2

 class bar{ 
     public function __construct(){}

     public function w(){
        return new PDO(...); 
     }

     public function x(){
        return new StdClass;
     }

     public function y(){
        return new Reflection; 
     }
     public function z(){
        return new SessionHandler; 
     }
  }

现在,根据上面两个例子,我想知道这两个调用是否占用相同数量的内存,或者用其他方式快速执行。

$foo = new foo(); 

### VS

$bar = new bar();
$bar->w(); 

我理解类foo仅在其实例中实例化4个对象,而类bar在调用方法w()时有一个实例。这似乎是,foo会占用更多内存,但我相信,php在读取类时解析所有内容,即使是未调用的方法,似乎也没有真正的区别。

2 个答案:

答案 0 :(得分:1)

  

我也相信,php会在读取类时解析所有内容,甚至是未调用的方法

你的信念至少是不知情的。

解析(第一阶段)是执行脚本的另一个阶段,实际执行它是另一个(第二阶段)阶段。

PHP在执行之前不执行任何代码(第二阶段),它只会将(第一阶段)代码的文本形式编译为更紧凑的二进制文件表示称为操作码 - 类似于任何CPU中电子设备所理解的操作码。

这就是PHP模块名为 opcode cachers 的原因 - 缓存操作码并跳过文本表示的解析(第一阶段)。

内存最有效的方法是实例化资源lazily

class Foo
{
    private $x;

    public function __construct()
    {
        //keep the constructor as lightweight as possible, ALWAYS
    }

    public function getX() {
        if(!$this->x) {
             $this->x = new X();
        }
        return $this->x;
    }
}

答案 1 :(得分:1)

案例1:

 public function __construct()
 {
   $a = new PDO(...);
   $b = new StdClass; 
   $c = new Reflection; 
   $d = new SessionHandler; 
 }

对于这个例子,PHP将为变量$ a,$ b,$ c和$ d分配内存。当构造函数方法完成执行时,这些对象的ref-count将立即命中0,这意味着在下一个收集周期中它们将从内存中删除。

案例2:

public function w(){
    return new PDO(...); 
 }

 public function x(){
    return new StdClass;
 }

 public function y(){
    return new Reflection; 
 }
 public function z(){
    return new SessionHandler; 
 }

方法w,x,y和z各自返回各种对象的实例。只要ref-count>>这些对象将被保存在存储器中。 0

示例:

$bar = new bar();
$bar->w(); //Returned object is not assigned to any variable, so it will be destroyed -> ref-count = 0
$x = $bar->x(); //ref-count = 1
$x2 = $x; //ref-count = 2
unset($x); //ref-count = 1
unset($x2); //ref-count = 0, bye-bye object

为了理解PHP内存管理的幕后的内容,可能有兴趣阅读以下手册页:

回答问题

"I would like to know if these two calls, occupy the same amount of memory, or in other terms which one would be executed fast"

那么你将在某些时候使用你脚本中的所有4个对象(我这么说?),所以只需选择一个模式并坚持使用它。 速度和内存消耗将取决于您将如何使用这些对象。