PHP - 内存泄漏 - 对象不会从 ram 中取消设置,gc_collect_cycles 什么也不做

问题描述

我编写了一个示例代码来了解如何在 PHP 上的长脚本中管理内存使用。

但我就是无法意识到这种行为

这段代码应该从未使用的对象中清除内存,但它几乎什么都不做

<?PHP

memory_using('start');

class a
{
    public $v = [];

    public function init()
    {
        for ($i = 0; $i <= 1000000; $i++)
        {
            $this->v[$i] = [rand(10000,99999),rand(10000,99999)];
        }
    }
}


$a = new a;

memory_using('before init');
$a->init();
memory_using('after init');

unset($a);
memory_using('after unset a');

gc_collect_cycles();
memory_using('after gc_collect_cycles');

xdebug_debug_zval('a');


function memory_using($where = null)
{
    echo(sprintf("Memory using: %4s %s\n",convertToReadableSize(memory_get_usage(true)),$where));

}

function convertToReadableSize($size)
{
    $base = log($size) / log(1024);
    $suffix = array("B","KB","MB","GB","TB");
    $f_base = floor($base);
    return round(pow(1024,$base - floor($base)),1) . $suffix[$f_base];
}

这是代码的结果:

Memory using:    2MB start
Memory using:    2MB before init
Memory using:  394MB after init
Memory using:  360MB after unset a
Memory using:  360MB after gc_collect_cycles
a: no such symbol

解决方法

memory_get_usage 的文档说明了以下参数: “将此设置为 true 以获取从系统分配的总内存,包括未使用的页面。”

您看到的内存包含尚未被其他应用程序声明的未使用内存(因为您正在立即收集内存转储)。如果在 gc_collect_cycles 之后添加 sleep 命令,您会看到数字会下降。