为什么GD在imagedestroy()时不释放内存? [英] Why GD doesn't release memory upon imagedestroy()?

查看:115
本文介绍了为什么GD在imagedestroy()时不释放内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need a PHP CLI script to do various image transformations via GD functions. The images are quite big so I need to squeeze as much memory as possible. However, imagedestroy() seems not to release memory when asked.

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

Consider following demo script '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;
    }
    ?>

通过发出以下命令来运行它:

Let's run it by issuing:

免费-m; ./test.php;免费-m

free -m;./test.php;free -m

示例结果:

                 total       used       free     shared    buffers     cached
    Mem:          7890       7072        818        561        218       2497
    -/+ buffers/cache:       4355       3534
    Swap:         8299          0       8299
    Res1 created: 109.76 MiB (+109.76 MiB)
    Res2 created: 218.77 MiB (+109.01 MiB)
    Res1 destroyed: 218.9 MiB (+140 kiB)
    Res2 destroyed: 888 kiB (-218.04 MiB)
                 total       used       free     shared    buffers     cached
    Mem:          7890       7072        817        561        218       2498
    -/+ buffers/cache:       4356       3534
    Swap:         8299          0       8299

如您所见,创建一张图像的成本为109-110MB.在创建第二个之后,我们已经用完了两倍.但是首先销毁并不会释放内存.只有在两个映像都销毁之后,所有资源的内存才被释放.

As you can see, creating one image costs 109-110MB. After creating second one we have double that used up. But destroying first doesn't release memory. All the resources' memory gets released only after both images are destroyed.

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

Why? Have I overlooked something? What should I do to amend it?

更新: 我将$ res1设置为null,然后将其完全取消设置.代码:

UPDATE: I added setting $res1 to null and then unsetting it altogether. Code:

    $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');

就在imagedestroy($ res2)之前;然后事情变得奇怪了:

right before imagedestroy($res2); and then things go strange:

    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"命令,仅在脚本结束后才释放内存.

According to 'free' command, the memory gets released only after script ended.

推荐答案

我想知道它是否是GC ...尝试在imagedestroy()之后运行gc_collect_cycles().远射,但你永远不知道...

I wonder if it's GC... try running gc_collect_cycles() after imagedestroy(). Long shot, but you never know...

这篇关于为什么GD在imagedestroy()时不释放内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆