首页 > 作文

Yii2 框架跑脚本时内存泄漏问题分析

更新时间:2023-04-06 10:17:57 阅读: 评论:0

现象

在跑 edu_ocr_img 表的归档时,每跑几万个数据,都会报一次内存耗尽

php fatal error: allowed memory sizeof 134217728 bytexhausted (triedtoallocate135168 bytes)

跟踪代码发现,是在插入时以下代码造成的:

eduocrtaskbackup::getdb()->createcommand()->batchinrt(eduocrtaskbackup::tablename(), $fields, $data)->execute();

execute 之后会造成使用内存涨上去,并且在之后 unt 所有变量内存也会有一部分不会删除,直到内存耗尽。

于是跟踪到 yii2中execute的具体代码块发现在记录 log 的时候会将使用很高的内存,分析代码之后得出造成泄漏的代码块如下:

造成泄漏的代码块

/** * logs a message with the given type and cate双曲线焦点三角形gory. * if [[tracele医药学院vel]] is greater than 0, additional call stack information about * the application code will be logged as well. * @param string|array $message the message to be logged. this can be a simple string or a more新春快乐祝福语 * complex data structure that will be handled by a [[target|log target]]. * @param integer $level the level of the message. this must be one360急救箱打不开 of the following: * `logger::level_error`, `logger::level_warning`, `logger::level_info`, `logger::level_trace`, * `logger::level_profile_begin`, `logger::level_profile_end`. * @param string $category the category of the message. */public function log($message, $level, $category = 'application'){    $time = microtime(true);    $traces = [];    if ($this->tracelevel > 0) {        $count = 0;        $ts = debug_backtrace(debug_backtrace_ignore_args);        array_pop($ts); // remove the last trace since it would be the entry script, not very uful        foreach ($ts as $trace) {            if (ist($trace['file'], $trace['line']) && strpos($trace['file'], yii2_path) !== 0) {                unt($trace['object'], $trace['args']);                $traces[] = $trace;                if (++$count >= $this->tracelevel) {                    break;                }            }        }    }        // 这里是造成内存的罪魁祸首    $this->messages[] = [$message, $level, $category, $time, $traces];    if ($this->flushinterval > 0 && count($this->messages) >= $this->flushinterval) {        $this->flush();    }}

造成内存泄漏的原因分析

在 yii2框架中的 vendor/yiisoft/yii2/log/logger.php:156 log函数的156行之后会判断 count($this->messages) >= $this->flushinterval
即:内存中存储的 message 的条数要大于等于预设的 $this->flushinterval 才会将内存中的message 刷到磁盘上去。

如果在刷新到磁盘之前就已经将 php.ini 设置的 128m 内存打满的话,会直接报错申请内存耗尽。

很多关于 yii2其他原因的内存泄漏的讨论

解决方案

在程序开始时,设置 flushinterval 为一个比较小的值
\yii::getlogger()->flushinterval = 100; // 设置成一个较小的值
在程序执行过程中,每次 execute 之后对内存中的 message 进行 flush
\yii::getlogge眼角鱼尾纹r()->flush(true); // 参数传 true 表示每次都会将 message 清理到磁盘中

本文发布于:2023-04-06 10:17:55,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/de20e1f3e1a4d7722e9296f5971f0abd.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Yii2 框架跑脚本时内存泄漏问题分析.doc

本文 PDF 下载地址:Yii2 框架跑脚本时内存泄漏问题分析.pdf

标签:内存   代码   会将   磁盘
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图