我试图理解PHP在这两个例子中如何处理内存消耗。
// 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(){}
}
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在读取类时解析所有内容,即使是未调用的方法,似乎也没有真正的区别。
答案 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个对象(我这么说?),所以只需选择一个模式并坚持使用它。 速度和内存消耗将取决于您将如何使用这些对象。