一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - 關于Yii2框架跑腳本時內存泄漏問題的分析與解決

關于Yii2框架跑腳本時內存泄漏問題的分析與解決

2021-09-18 16:39麥葉 PHP教程

這篇文章主要給大家介紹了關于Yii2框架跑腳本時內存泄漏問題的分析與解決方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Yii2具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

現象

在跑 edu_ocr_img 表的歸檔時,每跑幾萬個數據,都會報一次內存耗盡

PHP Fatal error:  Allowed memory size of 134217728 bytesexhausted (tried toallocate 135168 bytes)

跟蹤代碼發現,是在插入時以下代碼造成的:

EduOCRTaskBackup::getDb()->createCommand()->batchInsert(EduOCRTaskBackup::tableName(), $fields, $data)->execute();

execute 之后會造成使用內存漲上去,并且在之后 unset 所有變量內存也會有一部分不會刪除,直到內存耗盡。

于是跟蹤到 Yii2中execute的具體代碼塊發現在記錄 log 的時候會將使用很高的內存,分析代碼之后得出造成泄漏的代碼塊如下:

造成泄漏的代碼塊

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * 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;
    }
   }
  }
 }
 
 // 這里是造成內存的罪魁禍首
 $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其他原因的內存泄漏的討論
https://github.com/yiisoft/yii2/issues/13256

解決方案

在程序開始時,設置 flushInterval 為一個比較小的值

?
1
\Yii::getLogger()->flushInterval = 100; // 設置成一個較小的值

在程序執行過程中,每次 execute 之后對內存中的 message 進行 flush

?
1
\Yii::getLogger()->flush(true); // 參數傳 true 表示每次都會將 message 清理到磁盤中

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。

原文鏈接:https://www.maiyewang.com/2019/11/30/yii2-框架跑腳本時內存泄漏問題分析/

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产91无毒不卡在线观看 | 日本福利视频网站 | 交换年轻夫妇HD中文字幕 | 免费观看视频高清在线 | 亚洲www在线| 欧美白人猛性xxxxx69交 | chinese老太granny| 91九色porny国产美女一区 | 艹b视频在线观看 | 色综合久久六月婷婷中文字幕 | 色人阁导航 | 四虎免费在线观看视频 | 亚洲精品久久中文字幕 | 久久精麻豆亚洲AV国产品 | 色噜噜狠狠狠综合曰曰曰88av | 亚洲视频1区 | 亚洲国产欧美在线人成aaaa20 | 国偷盗摄自产福利一区在线 | zoz.zzz色 | narutomanga玖辛奈之乳 | 12345国产精品高清在线 | 日本人作爰啪啪全过程 | 免费午夜影院 | 全肉一女n男np高h乳 | 亚洲第一人黄所 | 全日爱韩国视频在线观看 | 国产日韩欧美不卡www | 欧美一区二区三区免费不卡 | 探花国产 | 青久草视频 | 欧美巨胸| 日本天堂视频 | 青青青手机视频在线观看 | 97精品国产自在现线免费 | 无人区大片免费播放器 | 精品一区二区三区高清免费观看 | 国产精品久久久久久久久久久威 | 1024免费观看完整版在线播放 | 99精品视频在线观看免费 | 久久黄色录像 | 亚洲社区在线 |