在 Symfony 应用程序中使用 Dompdf 识别和解决内存问题

问题描述 投票:0回答:1

问题描述

我在使用 Dompdf 生成 PDF 文件时在 Symfony 应用程序中遇到内存不足问题。我怀疑 Dompdf 库中可能存在内存泄漏。为了进行调查,我编写了一个脚本来创建多个 PDF 文件并监控内存使用情况。

use Dompdf\Dompdf;

ini_set('memory_limit', '20M');

print memory_get_usage() . PHP_EOL;

for ($i = 0; $i < 1000; $i ++) {
    print memory_get_usage() . PHP_EOL;
    createPDF();
}

print memory_get_usage() . PHP_EOL;

function createPDF () {
    // instantiate and use the dompdf class
    $dompdf = new Dompdf();
    $dompdf->loadHtml('hello world');
    // (Optional) Setup the paper size and orientation
    $dompdf->setPaper('A4', 'landscape');
    // Render the HTML as PDF
    $dompdf->render();
}

但是,运行此脚本会导致以下错误:

PHP Fatal error: Allowed memory size of 20971520 bytes exhausted (tried to allocate 12288 bytes) in path/to/vendor/dompdf/dompdf/src/Css/Stylesheet.php on line 281

问题

我怀疑 Dompdf 库中可能存在内存泄漏。如何验证该问题是否确实与 Dompdf 有关,或者是否存在其他潜在问题导致内存耗尽?

附加信息

  • Symfony 版本:4.4.36
  • Dompdf版本:2.0.3
  • PHP版本:7.4.33
php dompdf
1个回答
0
投票

问题是 PHP 垃圾收集器没有启动。

如果在

gc_collect_cycles()
中添加
createPDF()
,则可以强制进行垃圾回收。

您可以通过以下方式跟踪 GC:

php -dmemory_limit=7M -dxdebug.mode=gcstats -dxdebug.start_with_request=yes min.php

并在 /tmp/ 或您设置 XDebug 输出的任何位置查找

gcstats
文件。

那么为什么垃圾收集器没有启动呢?好吧,按照https://www.php.net/manual/en/features.gc.collecting-cycles.php

当垃圾收集器打开时,只要根缓冲区满了,就会执行如上所述的循环查找算法。根缓冲区的固定大小为 10,000 个可能的根(尽管您可以通过更改 PHP 源代码中 Zend/zend_gc.c 中的 GC_THRESHOLD_DEFAULT 常量并重新编译 PHP 来更改此设置)。当垃圾收集器关闭时,循环查找算法将永远不会运行。但是,无论垃圾收集机制是否已使用此配置设置激活,可能的根将始终记录在根缓冲区中。

由于 a

DomPdf
实例每次迭代都会占用相当大的内存块(其中很多位于
FontMetrics
缓存中),根缓冲区中没有足够的对象(它是一个小库)来生成 GC在内存耗尽之前。

如果您在

gc_status()
结束时运行
createPdf
,您会发现运行一次后您仅获得约 150 个根(取决于所选的适配器)。对于 20M,您将获得大约 7000 个根,低于 10k 阈值。如果将限制增加到 40M,脚本会成功完成,并且 8 次 GC 运行永远不会耗尽内存:

Garbage Collection Report
version: 1
creator: xdebug 3.2.0 (PHP 8.2.1)

Collected | Efficiency% | Duration | Memory Before | Memory After | Reduction% | Function
----------+-------------+----------+---------------+--------------+------------+---------
    87815 |    878.15 % | 12.88 ms |      28461832 |      5090000 |    82.12 % | Dompdf\Css\Stylesheet::apply_styles
    88140 |    881.40 % | 14.66 ms |      28556032 |      5090000 |    82.18 % | Dompdf\Css\Stylesheet::apply_styles
    88140 |    881.40 % | 15.01 ms |      28556032 |      5090000 |    82.18 % | Dompdf\Css\Stylesheet::apply_styles
    88140 |    881.40 % | 15.43 ms |      28556032 |      5090000 |    82.18 % | Dompdf\Css\Stylesheet::apply_styles
© www.soinside.com 2019 - 2024. All rights reserved.