使用symfony2和swiftmailer进行内存泄漏

skr*_*led 3 php swiftmailer symfony

我正在使用symfony2命令作为cron作业向群发成员发送批量电子邮件.

实际代码:

$output->writeln('Before: '.(memory_get_usage() / 1024 / 1024));

$mailer->send($m);

$output->writeln('After: '.(memory_get_usage() / 1024 / 1024));
Run Code Online (Sandbox Code Playgroud)

我的结果:

Before: 182.38 MB
After: 183.73 MB
Run Code Online (Sandbox Code Playgroud)

每次我发送电子邮件时,swiftmailer都会消耗额外的1 + MB内存.这似乎不对,但每次发送新消息时内存都会增加.我在这里做错了吗?

Jiv*_*van 5

SwiftMailer内存假脱机系统

你指出的问题实际上是一个解决方案,而不是一个问题.你没有做错任何事情,这是由于SwiftMailer内部发送电子邮件的方式.

根据send()方法,SwiftMailer实际上并不发送任何内容,而只是将其放入他的假脱机中.默认情况下,假脱机选项是memory,并且在内核终止之前发生假脱机刷新.所以没有机会memory_get_usage()告诉你内存已经被释放(因为很明显,你的脚本仍在运行,SwiftMailer尚未刷新它的假脱机).

从Symfony2文档:

当您使用假脱机将电子邮件存储到内存时,它们将在内核终止之前发送.这意味着只有在没有任何未处理的异常或任何错误的情况下执行整个请求时才会发送电子邮件.

使用文件假脱机系统

如果此假脱机选项导致您出现问题,则可以切换到File假脱机选项.

可以通过改变这个来完成:

# app/config/config.yml
swiftmailer:
    # ...
    spool: { type: memory }
Run Code Online (Sandbox Code Playgroud)

对此:

# app/config/config.yml
swiftmailer:
    # ...
    spool:
        type: file
        path: /path/to/spool
Run Code Online (Sandbox Code Playgroud)

然后,您可以将cron作业配置为自动并定期刷新假脱机:

$ php app/console swiftmailer:spool:send --env=prod
Run Code Online (Sandbox Code Playgroud)

不使用线轴

或者,您可以选择根本不使用假脱机系统,这意味着您在执行脚本期间将发送所有电子邮件.它可以帮助您摆脱内存问题,但可能会损害您的用户,具体取决于您是否在请求页面时发送邮件.但是,正如你在cron工作中所做的那样,在你的情况下它肯定不会是一个问题.可能有一天会.


小智 5

我有一个类似的内存问题与swiftmailer发送电子邮件.似乎插件会创建这些内存泄漏,因此不必删除事件调度程序代码,只需禁用插件(就您的情况而言,使用您自己的解决方案进行修补).

使用simfony2,在配置中禁用日志记录很容易:

swiftmailer:
    logging: false
Run Code Online (Sandbox Code Playgroud)

或使用多个邮件程序:

swiftmailer:
    mailers:
        my_mailer:
            logging: false
Run Code Online (Sandbox Code Playgroud)

在我的情况下,发送~1500封电子邮件,内存增长到大约100MB(仅仅因为记录器),现在> 0.2MB.

我知道这有点晚了,但也许对于遇到同样问题的人来说这可能是有用的.:-)