为什么GD在imagedestroy()时不释放内存?

2024-02-07

我需要一个 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;
    }
    ?>

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

自由-m;./test.php;自由-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。创建第二个后,我们已经用完了两倍。但首先销毁并不会释放内存。只有在两个图像都被销毁后,所有资源的内存才会被释放。

为什么?我是不是忽略了什么?我应该做什么来修改它?

更新: 我添加了将 $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');

就在 imagedestroy($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...尝试运行gc_collect_cycles() after imagedestroy()。可能性很大,但你永远不知道......

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么GD在imagedestroy()时不释放内存? 的相关文章

随机推荐

  • 用 Java 调高/调低计算机音量?

    我想用一个命令来调高或调低计算机的主音量 100 0 我看到我可以使用FloatControl 但我不知道如何使用它 看看看看使用JavaSound控制主音量 http www coderanch com t 492931 java jav
  • 使用 GTM 在一个容器中实施两个 Analytics 属性

    我想在两个包含相同网站 cms 代码但内容语言不同的域上实施 Google 跟踪代码管理器 因此 我想使用一个容器 一个 GTM 代码 其中包含两个标签 一个标签包含domainA com 的UA 代码段 另一个标签包含domainB co
  • 需要 Postgres 触发器和函数方面的帮助

    我有一个查找表 其中包含一列来源 来自通过我创建的 Web 服务 API 捕获的各种硬编码活动 以及应与其关联的各个品牌 这样我就可以为品牌为空的记录赋予品牌 以便可以通过营销自动化工具使用特定模板来欢迎它们 我最终会弃用这个 API 并用
  • 学说 2 - 查询生成器条件查询... If 语句?

    我的查询是 doctirne 2 我在用户中有一个状态字段 私人或 民众 我希望能够运行此查询并显示所有评论 其中 仅当 userid 当前登录时 状态 公共和私有 用户 ID 我知道 loggerUserVarID q this gt e
  • 如何在 Azure ML 服务中注册本地训练的机器学习模型?

    我正在尝试Azure 机器学习服务 https azure microsoft com en us services machine learning service 用于机器学习部署 我已经在计算 VM 上训练了一个模型并将其保存为 pi
  • c++ - 如何使用裸新初始化智能点?

    我正在尝试学习新的 C 标准 但在使用智能指针时我遇到了不足 这是我正在编写的一个不想运行的程序的代码 include
  • Julia 并行编程 - 使现有功能可供所有工作人员使用

    我面临以下问题 我有一个函数叫做火车模型在单个线程上运行很长时间 当它完成计算时 它返回一个函数作为输出参数 我们称之为f 当我询问这个 的类型时f 朱莉娅返回 具有 1 种方法的通用函数 我不确定最后一条信息对阅读本文的人是否有用 现在在
  • Excel biff5 到 biff8 转换

    我的系统使用 Apache POI 来管理一些 xls 文件 现在我有近 300 个 xls 文件 但它们似乎是旧格式 所以我得到了这个异常 提供的电子表格似乎是 Excel 5 0 7 0 BIFF5 格式 POI 仅支持 BIFF8 格
  • 遇到错误:java.lang.NoClassDefFoundError:com/google/common/collect/ImmutableList$Builder

    我是使用 EclipseIDE 和 TestNG 来使用 Selenium WebDriver 的新手 我目前正在 Eclipse 中通过 TestNG 运行此示例代码 import org openqa selenium By impor
  • 如何将 jQuery.serialize() 数据转换为 JSON 对象?

    当表单包含多个输入数组字段时 是否有更好的解决方案来转换已通过 jQuery 函数 serialize 序列化的表单数据 我希望能够将表单数据转换为 JSON 对象 以重新创建一些其他信息表 那么告诉我一个更好的方法来将序列化字符串转换为
  • .Net 中的钥匙锁

    我有一个 Azure 服务总线队列 我正在其中接收 1 到 10 条具有相同 密钥 的消息 其中一条消息需要通过长时间运行的操作来处理 完成后 数据库将被更新 其他消息将对其进行检查 但是 与此同时 其他消息将重新排队 以便进程不会丢失 但
  • 图像中的第四个通道是什么?

    使用随机生成图像时该列意味着什么np random randint img np random randint 255 size 4 4 3 dtype uint8 这将创建一个 4 x 4 像素 3 列的矩阵 img np random
  • 在 Clojure 中获取函数的参数类型提示

    我正在寻找提取函数参数的类型提示信息 但我似乎找不到访问该信息的方法 例如 假设我有以下功能 defn Double do something String a String b 5 0 拉取标签很简单 tag meta do someth
  • 这些“未定义引用 __glut*WithExit”OpenGL 链接器错误的含义是什么? [复制]

    这个问题在这里已经有答案了 原问题 警告 路过GLfloat for converting 2 of空白 glutSolidSphere GLdouble GLint 闪烁 警告 路过GLfloat for converting 3 of空
  • Swift 中多维数组的语法是什么?

    CO 粉丝 在你下结论之前 它是一个重复的 有 2 种不同风格的数组 看来我问的是不太受欢迎的一种 到目前为止 我只看到了锯齿状数组的语法 例如 Int 但我找不到任何有关平面多维数组的信息 那么类型的语法是什么 比如二维数组Ints 以及
  • 如何使用 Javascript/underscorejs 找到包含对象的数组的交集?

    我不知道如何找到这组数组的交集 name product1 light 1 name product2 light 2 name product5 light 5 name product4 light 4 name product2 li
  • 如何将数据数组导入到 Hive 表中的单独行中?

    我正在尝试将以下格式的数据导入配置单元表 identifier id 1 dataA dataA 1 identifier id 2 dataA dataA 2 我有多个这样的文件 我希望每个 在表中形成一行 这是我尝试过的 CREATE
  • 图形解析错误

    我尝试使用 python 和 igraph 库创建 graphml 文件 我可以构建 igraph 的图形对象并将其写入文件 g write graphml mygraph graphml 一切似乎都很成功 但是当我尝试使用以下命令将文件读
  • 在java中解析XML属性

    我有一个与此类似的xml
  • 为什么GD在imagedestroy()时不释放内存?

    我需要一个 PHP CLI 脚本来通过 GD 函数执行各种图像转换 图像很大 所以我需要压缩尽可能多的内存 然而 当被要求时 imagedestroy 似乎不会释放内存 考虑以下演示脚本 test php usr bin php5