關(guān)于Yii2框架跑腳本時(shí)內(nèi)存泄漏問題的分析與解決
現(xiàn)象
在跑 edu_ocr_img 表的歸檔時(shí),每跑幾萬個(gè)數(shù)據(jù),都會(huì)報(bào)一次內(nèi)存耗盡
PHP Fatal error: Allowed memory size of 134217728 bytesexhausted (tried toallocate 135168 bytes)
跟蹤代碼發(fā)現(xiàn),是在插入時(shí)以下代碼造成的:
EduOCRTaskBackup::getDb()->createCommand()->batchInsert(EduOCRTaskBackup::tableName(), $fields, $data)->execute();
execute 之后會(huì)造成使用內(nèi)存漲上去,并且在之后 unset 所有變量?jī)?nèi)存也會(huì)有一部分不會(huì)刪除,直到內(nèi)存耗盡。
于是跟蹤到 Yii2中execute的具體代碼塊發(fā)現(xiàn)在記錄 log 的時(shí)候會(huì)將使用很高的內(nèi)存,分析代碼之后得出造成泄漏的代碼塊如下:
造成泄漏的代碼塊
/** * Logs a message with the given type and category. * If [[traceLevel]] 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 one 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 useful foreach ($ts as $trace) { if (isset($trace['file'], $trace['line']) && strpos($trace['file'], YII2_PATH) !== 0) { unset($trace['object'], $trace['args']); $traces[] = $trace; if (++$count >= $this->traceLevel) { break; } } } } // 這里是造成內(nèi)存的罪魁禍?zhǔn)? $this->messages[] = [$message, $level, $category, $time, $traces]; if ($this->flushInterval > 0 && count($this->messages) >= $this->flushInterval) { $this->flush(); } }
造成內(nèi)存泄漏的原因分析
在 Yii2框架中的 vendor/yiisoft/yii2/log/Logger.php:156 log函數(shù)的156行之后會(huì)判斷 count($this->messages) >= $this->flushInterval
即:內(nèi)存中存儲(chǔ)的 message 的條數(shù)要大于等于預(yù)設(shè)的 $this->flushInterval 才會(huì)將內(nèi)存中的message 刷到磁盤上去。
如果在刷新到磁盤之前就已經(jīng)將 php.ini 設(shè)置的 128M 內(nèi)存打滿的話,會(huì)直接報(bào)錯(cuò)申請(qǐng)內(nèi)存耗盡。
很多關(guān)于 YII2其他原因的內(nèi)存泄漏的討論
https://github.com/yiisoft/yii2/issues/13256
解決方案
在程序開始時(shí),設(shè)置 flushInterval 為一個(gè)比較小的值
\Yii::getLogger()->flushInterval = 100; // 設(shè)置成一個(gè)較小的值
在程序執(zhí)行過程中,每次 execute 之后對(duì)內(nèi)存中的 message 進(jìn)行 flush
\Yii::getLogger()->flush(true); // 參數(shù)傳 true 表示每次都會(huì)將 message 清理到磁盤中
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)我們的支持。
上一篇:PHP 進(jìn)程池與輪詢調(diào)度算法實(shí)現(xiàn)多任務(wù)的示例代碼
欄 目:PHP編程
本文標(biāo)題:關(guān)于Yii2框架跑腳本時(shí)內(nèi)存泄漏問題的分析與解決
本文地址:http://mengdiqiu.com.cn/a1/PHPbiancheng/11084.html
您可能感興趣的文章
- 04-02關(guān)于txt數(shù)據(jù)庫php的信息
- 01-11thinkphp框架類庫擴(kuò)展操作示例
- 01-11php 實(shí)現(xiàn)簡(jiǎn)單的登錄功能示例【基于thinkPHP框架】
- 01-11Laravel框架Blade模板簡(jiǎn)介及模板繼承用法分析
- 01-11Laravel框架基礎(chǔ)語法與知識(shí)點(diǎn)整理【模板變量、輸出、include引入
- 01-11Laravel框架Eloquent ORM刪除數(shù)據(jù)操作示例
- 01-11Laravel框架Eloquent ORM修改數(shù)據(jù)操作示例
- 01-11Laravel框架Eloquent ORM簡(jiǎn)介、模型建立及查詢數(shù)據(jù)操作詳解
- 01-11laravel5.1框架下的批量賦值實(shí)現(xiàn)方法分析
- 01-11laravel5.5框架的上傳圖片功能實(shí)例分析【僅傳到服務(wù)器端】


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02php本站才可以請(qǐng)求數(shù)據(jù) php本地?cái)?shù)據(jù)庫
- 04-02關(guān)于txt數(shù)據(jù)庫php的信息
- 04-02php打印請(qǐng)求數(shù)據(jù) php打印輸出結(jié)果
- 04-02網(wǎng)頁里php操作數(shù)據(jù)庫 php網(wǎng)頁例子
- 04-02php插入數(shù)據(jù)庫為亂碼 php連接數(shù)據(jù)庫亂
- 04-02php數(shù)據(jù)庫地址 phpstudy 數(shù)據(jù)庫
- 04-02php數(shù)據(jù)庫數(shù)據(jù)相加 php數(shù)據(jù)庫添加數(shù)據(jù)
- 04-02數(shù)據(jù)權(quán)限架構(gòu)思路php 數(shù)據(jù)權(quán)限設(shè)計(jì)方
- 04-02php數(shù)據(jù)庫輸入變量 php里輸出數(shù)據(jù)庫數(shù)
- 04-02php如何用導(dǎo)入數(shù)據(jù) php用來導(dǎo)入其他文
隨機(jī)閱讀
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery