关于ThinkPHP执行长时间任务可能导致PHP使用内存越来越大的问题
ThinkPHP执行长时间任务时,可能导致PHP使用内存越来越大,最后因为内存超出配置限额而程序挂掉。
其实这在很久以前就无意之中发现的一个问题。
3.x之前有这个问题,5.0以后的,应该是已修复了的(我看了下5.0.6)。
这个问题,一句话说明,是因为ThinkPHP在记录系统日志的时候出现的问题(ThinkPHP在运行过程中,会记录自己的运行日志,根据是否开启DEBUG模式,记录的日志信息有不同,不多说)。
因为一个进程执行完,会在很多地方打点记录日志,但是为了提高写日志文件的效率,ThinkPHP先是给所有日志信息记录在内存里(一个数组),最后一次性写入文件。正是因为这个科学的做法,导致了可能出现的不科学的结果,那就是,在长时间执行循环任务时,尤其是会循环操作数据库时而又开启了DEBUG模式的情况下(日志信息会记录数据库语句等,信息较多),就会有大量的日志信息,越来越多的存入这个数组里,造成内存占用越来越大,最终可能导致程序奔溃。
看代码:
/**
* 文件:ThinkPHP\Library\Think\Log.class.php
* 记录日志 并且会过滤未经设置的级别
* @static
* @access public
* @param string $message 日志信息
* @param string $level 日志级别
* @param boolean $record 是否强制记录
* @return void
*/
static function record($message,$level=self::ERR,$record=false) {
if($record || false !== strpos(C('LOG_LEVEL'),$level)) {
self::$log[] = "{$level}: {$message}\r\n";
}
}
如果遇到这种情况,修改一下此方法即可。这里提供一个最简单的修改方法(在未开启DEBUG模式的情况下,直接不记录日志):
static function record($message,$level=self::ERR,$record=false) {
if( !APP_DEBUG ) return false; //在debug为开启情况下,不记录日志 by ztg
if($record || false !== strpos(C('LOG_LEVEL'),$level)) {
self::$log[] = "{$level}: {$message}\r\n";
}
}
这样,当执行长时间的循环任务时,给DEBUG关闭后,则无日志记录,可不会再出现这种情况了。
另外,附带ThinkPHP5.0后的代码,可以看出,在保存日志的机制上,已经完全变了,会循环的定量保存,然后清空内容,避免这种情况:
/**
* 记录调试信息
* @param mixed $msg 调试信息
* @param string $type 信息类型
* @return void
*/
public static function record($msg, $type = 'log')
{
self::$log[$type][] = $msg;
if (IS_CLI && count(self::$log[$type]) > 100) {
// 命令行下面日志写入改进
self::save();
}
} /**
* 保存调试信息
* @return bool
*/
public static function save()
{
if (!empty(self::$log)) {
if (is_null(self::$driver)) {
self::init(Config::get('log'));
} if (!self::check(self::$config)) {
// 检测日志写入权限
return false;
} if (empty(self::$config['level'])) {
// 获取全部日志
$log = self::$log;
if (!App::$debug && isset($log['debug'])) {
unset($log['debug']);
}
} else {
// 记录允许级别
$log = [];
foreach (self::$config['level'] as $level) {
if (isset(self::$log[$level])) {
$log[$level] = self::$log[$level];
}
}
} $result = self::$driver->save($log);
if ($result) {
self::$log = [];
} return $result;
}
return true;
}
关于ThinkPHP执行长时间任务可能导致PHP使用内存越来越大的问题的更多相关文章
- thinkphp nginx php-fpm url rewrite 导致 404 错误
## thinkphp nginx php-fpm url rewrite 导致 404 错误 之前thinkphp的系统部署在apache上,考虑到在并发性能nginx比apache强悍得多,所以在 ...
- 【转】STM32擦除内部FLASH时间过长导致IWDG复位分析
@20119-01-29 [小记] STM32擦除内部FLASH时间过长导致IWDG复位分析
- 一次vm 虚拟机时间倒流而导致的oracle 数据库启动故障
一次vm 虚拟机时间倒流而导致的oracle 数据库启动故障 本文是原创文章.若转载请注明出处: http://blog.csdn.net/msdnchina/article/details/3878 ...
- Prometheus由于时间不同步导致数据不显示
原文链接:Prometheus由于时间不同步导致数据不显示 问题 部署 prometheus 后,访问前端界面发现: 这是由于你windows机器与部署prometheus服务器的时间不同步导致的. ...
- apache不断占内存过大,导致虚拟机内存不足,处理方法。
我用512M的vps,访问量不大,但内存占用很大,甚至宕机. 我用top,然后shitf+m发现,httpd占用内存极大.经过网上找资料设置后,用过一段时间终于没再出现内存问题了. 首先查找配置文件的 ...
- 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug
前言: 话说昨晚还是前晚,写了一篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上) 文章写到最后时,多了很多莫名奇妙的问题!!! 为了解决了这些莫名奇妙的问题,我又战斗了2 ...
- 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self
前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...
- ridge regression 无惩罚,导致预测结果空间过大而无实用价值
[ biased regression methods to reduce variance---通过偏回归来减小方差] https://onlinecourses.science.psu.edu/s ...
- IIS日志文件越来越大导致C盘空间变小处理方法
问题概述 C:\inetpub\logs\LogFiles\W3SVC文件夹越来越大,IIS日志会消耗大量的硬盘空间,有潜在写满整个硬盘空间的风险,为了解决这个问题很多用户会选择关闭日志,但显然IIS ...
随机推荐
- ZooKeeper概念与应用
Zookeeper是开源的分布式协调服务,提供了分布式数据一致性的解决方案. Zookeeper 可用作配置中心和分布式锁服务,在 Dubbo.Kafka.Spark等分布式集群上得到广泛应用. ZN ...
- [EZOJ1007] 神奇的三角形
Description 求 \(\sum\limits_{i=0}^{n-1}\sum\limits_{j=0}^{i}C(i,j)\times (j+1)^m\operatorname{mod}99 ...
- windows server 2008 R2 开启远程桌面
1.计算机 ——属性 2.远程设置 3.远程桌面-允许运行任意版本远程连接-选择用户-添加用户:Administrator;或是可以是其他非管理员用户(默认的系统管理员已经被授予了访问权限); 点确 ...
- C#实现RSA加密与解密、签名与认证(转)
一.RSA简介 RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的.RSA取名来自开发他们三者的名字.RSA是目前最有影响力 ...
- 基于mave的dubbo分别架构
开始前,先看一下demo项目工程结构: 1.抽离接口 dubbo-api工程,根据业务抽离接口,deploy到mave nexus. public interface TestService { /* ...
- 2017 SCNUCPC 解题报告
校内赛题目.解题思路.参考代码一览 A. Blackstorm's Blackstore Problem Description Blackstorm is going to open a black ...
- 商业智能BI-基础理论知识总结 ZT
因为要加入一个BI项目,所以最近在研究BI相关的知识体系,由于这个方面的知识都是比较零散,开始都很多概念,不知道从何入手,网上找的资料也不多,特别是实战案例方面更少,这里还是先把理论知识理解下吧,分享 ...
- mysql5.7 安装和多源复制实践
MySQL 5.7发布后,在复制方面有了很大的改进和提升.比如开始支持多源复制(multi-source)以及真正的支持多线程复制了.多源复制可以使用基于二进制日子的复制或者基于事务的复制.下面我们说 ...
- Android中处理崩溃闪退错误
Android中处理崩溃闪退异常 大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试, ...
- Python:GUI之tkinter学习笔记之messagebox、filedialog
相关内容: messagebox 介绍 使用 filedialog 介绍 使用 首发时间:2018-03-04 22:18 messagebox: 介绍:messagebox是tkinter中的消息框 ...