首页 > 解决方案 > 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), 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

标签: phpmemory-managementmemory-leaks

解决方案


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

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


推荐阅读