带有对象的PHP内存不稳定数组
测试一:带有对象的PHP内存不稳定数组,php,Php,测试一: class Entity { } $entities = array(); echo "START: ". number_format(memory_get_usage()) . "\n"; for($i = 0; $i < 100000; ++$i) { $entities[] = new Entity(); } echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n"; unset($entiti
class Entity { }
$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
$entities[] = new Entity();
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";
class Entity { }
$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
$entity = new Entity();
$entities[] = &$entity;
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";
测试二:
class Entity { }
$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
$entities[] = new Entity();
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";
class Entity { }
$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
$entity = new Entity();
$entities[] = &$entity;
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";
在我遇到内存限制的问题后,我对它进行了一些尝试
在那之后,我想知道垃圾收集到底是如何工作的:
- 这就是这个数组占用更多内存的原因——它存储的是实际对象
- 此数组占用较少内存的原因是它只存储对对象的引用
$entities = array();
echo "START: ". number_format(memory_get_usage()) . "\n";
for($i = 0; $i < 100000; ++$i)
{
$entities[] = new Entity;
}
echo "BEFORE UNSET: ". number_format(memory_get_usage()) . "\n";
foreach($entities as &$entity) {
unset($entity);
}
unset($entities);
echo "AFTER UNSET: ". number_format(memory_get_usage()) . "\n";
$entities=array();
回声“开始:”。数字\格式(内存\获取\使用()。“\n”;
对于($i=0;$i<100000;++$i)
{
$entities[]=新实体;
}
回声“在未设置之前:”。数字\格式(内存\获取\使用()。“\n”;
foreach($entities as&$entity){
未结算(实体);
}
未结算(实体);
回声“未设置后:”。数字\格式(内存\获取\使用()。“\n”;
然后取消设置数组中的每个对象。您将获得与第二次尝试相同的结果:
例如:
开始:3237720未设置前:21297640
取消设置后:3237488 演示: 为什么测试一比测试二需要更多的内存 PHP为存储标识符分配的内存比为引用分配的内存多(您的第一个测试是按标识符分配的) 从: PHP引用是一个别名,它允许使用两个不同的变量 写入相同的值。从PHP5开始,对象变量不起作用 不再将对象本身作为值包含。它只包含一个对象 允许对象访问器查找实际对象的标识符。 通过参数发送、返回或分配给另一个对象时 变量,不同的变量不是别名:它们包含 指向同一对象的标识符 这使得标识符有点神奇,它们是经过特殊处理的 为什么php在测试一中取消设置数组后仍保留内存
unset
仅标记一个变量的内存以供GC的算法释放;它无法立即释放内存。当我运行您的第一个测试时,大量内存被释放(虽然没有第二个测试那么多,可能是因为分配了更大的大小)。您所说的这些对象仍然在那里是什么意思?@webbiedave它们仍然在内存中的某个地方。还没有超出范围。这基本上不是我的答案所说的吗?不。你的答案它存储的是实际对象是不正确的。您的回答也没有提到标识符,这些标识符绝不是实际对象(请尝试$entity=newentity();$entities[]=$entity;
)。我的回答也回答了他的第二个问题,即为什么与你的完全不同。标识符的优势是什么?为什么php使用标识符而不是引用?