Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么GD不';是否在imagedestroy()时释放内存?_Php_Memory_Gd - Fatal编程技术网

Php 为什么GD不';是否在imagedestroy()时释放内存?

Php 为什么GD不';是否在imagedestroy()时释放内存?,php,memory,gd,Php,Memory,Gd,我需要一个PHP CLI脚本通过GD函数进行各种图像转换。这些图像非常大,所以我需要尽可能多地压缩内存。但是,imagedestroy()在被询问时似乎不会释放内存 考虑以下演示脚本“test.php”: #!/usr/bin/php5 <?php $memory = [0=> memoryCheck()]; $res1 = imagecreatetruecolor(8192, 4096); memoryReport('Res1 create

我需要一个PHP CLI脚本通过GD函数进行各种图像转换。这些图像非常大,所以我需要尽可能多地压缩内存。但是,imagedestroy()在被询问时似乎不会释放内存

考虑以下演示脚本“test.php”:

    #!/usr/bin/php5
    <?php

    $memory = [0=> memoryCheck()];
    $res1 = imagecreatetruecolor(8192, 4096);
    memoryReport('Res1 created');
    $res2 = imagecreatetruecolor(8192, 4096);
    memoryReport('Res2 created');
    imagedestroy($res1);
    memoryReport('Res1 destroyed');
    imagedestroy($res2);
    memoryReport('Res2 destroyed');

    // memory reporting functions follow:
    function memoryCheck()
    {
        return (int) trim(substr(shell_exec('free -b'), 166, 11));
    }

    function format($value)
    {
        $val = \abs($value);
        $unit=array('B','kiB','MiB','GiB','TiB','PiB');
        return @round($val/pow(1024,($i=floor((($val==0)?0:log($val,1024))))),2).' '.$unit[$i];
    }

    function memoryReport($msg)
    {
        global $memory;

        $start = $memory[0];
        $prev = end($memory);
        $now = memoryCheck();

        echo sprintf("%s: %s (%s)\n", 
                        $msg, 
                        format($now-$start), 
                        (($diff=$now-$prev) <0) ? '-'. format($diff) : '+'. format($diff)
                    );
        $memory[] = $now;
    }
    ?>
正如您所看到的,创建一个映像需要109-110MB。在创建第二个之后,我们已经使用了两倍。但先销毁并不能释放内存。只有在两个映像都被销毁后,所有资源的内存才会被释放

为什么??我忽略了什么吗?我应该怎么做才能修改它

更新: 我添加了将$res1设置为null,然后将其全部取消设置。代码:

    $memory = [0=> memoryCheck()];
    $res1 = imagecreatetruecolor(8192, 4096);
    memoryReport('Res1 created');
    $res2 = imagecreatetruecolor(8192, 4096);
    memoryReport('Res2 created');
    imagedestroy($res1);
    memoryReport('Res1 destroyed');
    $res1 = null;
    memoryReport('Res1 is null');
    unset($res1);
    memoryReport('Res1 is unset');
    imagedestroy($res2);
    memoryReport('Res2 destroyed');
现在的结果是:

    Res1 created: 109.48 MiB (+109.48 MiB)
    Res2 created: 219.33 MiB (+109.85 MiB)
    Res1 destroyed: 219.5 MiB (+168 kiB)
    Res1 is null: 220.15 MiB (+668 kiB)
    Res1 is unset: 220.38 MiB (+232 kiB)
    Res2 destroyed: 2 MiB (-218.36 MiB)
还有,我补充道

    gc_collect_cycles();
    memoryReport('GC collect');
就在图像销毁之前($res2);然后事情变得很奇怪:

    Res1 created: 109.59 MiB (+109.59 MiB)
    Res2 created: 219.08 MiB (+109.5 MiB)
    Res1 destroyed: 219.21 MiB (+132 kiB)
    Res1 is null: 219.36 MiB (+148 kiB)
    Res1 is unset: 219.75 MiB (+408 kiB)
    GC collect: 220.57 MiB (+836 kiB)
    Res2 destroyed: 220.46 MiB (-108 kiB)

根据“free”命令,只有在脚本结束后才会释放内存。

我想知道它是否是GC。。。在
imagedestroy()之后尝试运行
gc\u collect\u cycles()
。很遥远,但你永远不知道…

请参阅更新的问题。添加这个gc\u collect\u cycles()实际上让事情变得更糟。我更糊涂了。嗯。。。对不起,我没有主意了。祝你好运imagedestroy()只会释放内存供PHP使用。它不一定会将内存释放回系统。PHP以块的形式从系统中分配内存。如果$res1使用的块恰好包含$res2(或任何其他变量)中的内容,则该块将不会被释放。除了尝试更改这些资源的创建顺序之外,您几乎无能为力。@cleong您应该将此评论作为答案发布。确实,请这样做,以便我可以奖励您的答案:)@cleong:请将您的评论作为答案发布,以便我可以奖励您的答案:)
    Res1 created: 109.59 MiB (+109.59 MiB)
    Res2 created: 219.08 MiB (+109.5 MiB)
    Res1 destroyed: 219.21 MiB (+132 kiB)
    Res1 is null: 219.36 MiB (+148 kiB)
    Res1 is unset: 219.75 MiB (+408 kiB)
    GC collect: 220.57 MiB (+836 kiB)
    Res2 destroyed: 220.46 MiB (-108 kiB)