Php 为什么内存使用统计数据中没有锯齿形状?
最近我做了这样的实验——新对象不断地在一个不间断的循环中生成,而不保存它们的任何引用,因此它们应该在最近的适当时刻被垃圾收集器销毁。唯一特别的是,对象在内存使用方面非常大——一个对象包含7000万个元素的数组。代码如下:Php 为什么内存使用统计数据中没有锯齿形状?,php,garbage-collection,Php,Garbage Collection,最近我做了这样的实验——新对象不断地在一个不间断的循环中生成,而不保存它们的任何引用,因此它们应该在最近的适当时刻被垃圾收集器销毁。唯一特别的是,对象在内存使用方面非常大——一个对象包含7000万个元素的数组。代码如下: class Temp { private $data; function __construct() { $this->data = range(1,70000000); } } while (true) { new T
class Temp {
private $data;
function __construct() {
$this->data = range(1,70000000);
}
}
while (true) {
new Temp();
}
我感到非常惊讶的是,内存使用图中并没有任何典型的锯齿形垃圾收集器行为。这是(阵列中有7000万个元素):
问题是-在哪里?
我最好的猜测是,对象的分配和收集过程开始同时工作,或者其他一些事情正在进行
编辑1:
当数组中的元素数减少到6000万时-我得到
锯齿形GC行为符合预期(阵列中有6000万个元素):
编辑2:
若数组中的元素数量增加(数组中有9000万个元素),我会得到一个反向锯齿图
看来7000万元素测试是介于这两种不同形状锯齿之间的一种边缘测试。但我不清楚背后的原因。你的实验没有以任何方式观察垃圾收集器。当引用计数为0时,所有对象都会被销毁,这并不是因为垃圾收集器将它们视为循环的一部分,因此也不是垃圾。您可以通过添加新的私有成员来调整脚本,例如
$cycle
,并在构造函数中分配一个自引用($this->cycle=$this
)。我相信你会看到不同的结果;但您可能需要减少数据量以适应可用内存。当引用计数为0时,对象仅标记为从内存中删除,但实际删除将由GC在其认为最合适的时间完成。您不能在同一时间销毁内存中所有未使用的对象,因此GC和锯齿行为会循环。不-我不需要自引用-在这种情况下,对象将永远存在,因此GC将永远不会收集它,因此在您建议的案例中很快会出现内存不足
错误。我们显然在讨论两个不同的垃圾收集器。祝你好运