【问题标题】:Stream Filter memory usage流过滤器内存使用情况
【发布时间】:2021-04-30 16:11:25
【问题描述】:

PHP v7.4.16

我有一个相当基本的流过滤器(它扩展了 php_user_filter),我用它来规范化 CSV 文件,因为它们被传输到另一个目的地(在这种情况下使用流包装器的 s3 存储桶)。

filter()函数的内容:

 while ($bucket = stream_bucket_make_writeable($in)) {

            // Replace any CRLF Windows line-endings with *nix \n
            $bucket->data = preg_replace('~(*BSR_ANYCRLF)\R~', "\n", $bucket->data);

            $encoding = mb_detect_encoding($bucket->data, mb_detect_order(), true);
            $bucket->data = strtolower($encoding) != "utf-8"
                ? iconv($encoding, "utf-8//IGNORE", $bucket->data)
                : $bucket->data;

            $consumed += $bucket->datalen;

            // Send bucket to downstream brigade
            stream_bucket_append($out, $bucket);
        }

        // Return the code that indicates that the userspace filter returned buckets in $out
        return \PSFS_PASS_ON;

我可以像这样成功使用过滤器:

 private function streamFileToS3($file_entity) {
        $source = fopen($file_entity->local_path, 'r');
        $dest = fopen($file_entity->s3_path, 'w');
        @\stream_filter_prepend($dest, 'csv', STREAM_FILTER_WRITE);
        $chunk_size = (10 * 1024 * 1024);
        while (!feof($source)) {
          
            $chunk = fread($source, $chunk_size);
            fwrite($dest, $chunk);
        }
        fclose($dest);
        fclose($source);
        return true;
    }

现在是重要的一点。

将过滤器附加到我要写入的文件句柄时,脚本会使用我期望的内存。

 @\stream_filter_prepend($dest, 'csv', STREAM_FILTER_WRITE);

但是当我尝试在文件句柄上使用过滤器时,我正在读取来自:

 @\stream_filter_prepend($source, 'csv', STREAM_FILTER_READ);

memory_get_usage() 的输出每次迭代都会增加 fread() 块的大小

有谁知道这是为什么,有什么办法可以解决吗?

提前致谢

【问题讨论】:

  • 您好,我以稍微不同的方式遇到了这个问题,但仍然涉及内存限制。我的解决方案是使用这个包:github.com/box/spout。你需要启用几个扩展,遗憾的是你需要稍微修改你的工作流程。
  • 嗨@Ballard,不幸的是,我不确定这是否能解决我的特定用例,但感谢您提及,我没有遇到过这个库。
  • 能否请您详细说明您所期望的差异,因为到目前为止我从中得到的是您的内部缓冲区已耗尽,您可以尝试在每次操作后刷新以避免内存泄漏可能跨度>

标签: php amazon-s3


【解决方案1】:

在花了更多时间调查之后,我遇到了几个其他人遇到类似问题的实例:

https://bugs.php.net/bug.php?id=78902 https://bugs.php.net/bug.php?id=79143

似乎在 PHP V7 中存在一些内存泄漏问题。由于我的环境使用的是 Docker,因此可以非常直接地测试一些其他版本以查看问题是否仍然存在。

在我的情况下,使用时出现了问题:

  • php:7.4.2-apache
  • php:7.4.18-apache

但是使用的时候问题好像解决了

  • php:8.0.5-apache

希望这可以帮助其他可能正在用这个头撞墙的人。

【讨论】:

    猜你喜欢
    • 2012-11-18
    • 1970-01-01
    • 2012-01-23
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 2015-02-03
    • 2012-05-30
    相关资源
    最近更新 更多