PHP脚本占用内存太多,解决方案
Fatal Error: Allowed memory size of xxxxxx bytes exhausted
今天遇到服务器很多自动任务的php脚本占用服务内存过多,并且程序不在运行了。
解决方法:
在运行PHP程序,通常会遇到“Fatal Error: Allowed memory size of xxxxxx bytes exhausted”的错误, 这个意味着PHP脚本使用了过多的内存,并超出了系统对其设置的允许最大内存。解决这个问题,首先需要查看你的程序是否分配了过多的内存,在程序没有问题的情况下,你可以通过一下方法来增加PHP的内存限制(memory_limit)。
检查php的内存限制值
为了查看这个值,你需要建立一个空的php文件,比如view-php-info.php。然后将一下代码贴到里面。
<?php phpinfo(); ?>
将这个脚本放到你的Web服务器上,然后在浏览器中调用它。这时你可以看到你的PHP环境配置的信息,其中有一部分是关于“memory_limit”的, 如下图:
注:你可以用这种方法来查看php的其他参数设置,不仅仅是memory_limit
memory_limit应该设为多少?
这个完全依赖于你的应用的要求。比如Wordpress,运行起核心代码需要32MB。Drupal 6则要求这个值最小为16MB,并推荐设置为32MB。如果你又安装不少的插件(plugins),尤其是那些要进行图像处理的模块,那么你可能需要128MB或更高的内存。
如何设置memory_limit
方法1: php.ini
最简单或常用的方法是修改php.ini
1.首先找到对你的网站生效的php.ini文件 由于有多个地方都可以设置php的参数,找到正确的配置文件,并进行更改是首先要做的一步。如果你上面的方法建立了php文件来查看其配置参数,则你可以找到“Loaded Configuration File”这一项,以下是个例子:
对于Linux用户,你可以通过执行“php -i | grep Loaded Configuration File”来找到对应的配置文件。而Windows用户,你可以尝试修改你的php安装目录下的php.ini。
2.编辑php.ini 在php.ini中,找到“memory_limit”这一项,如果没有,你可以在文件的尾部自己增加这个参数。以下是一些设置范例
memory_limit = 128M ; 可以将128M改为任何你想设置的值
保存文件
3.重启web 服务器 如果是web服务器使用Apache, 则执行:
httpd restart
有些情况下,你可能不被允许私修改php.ini。比如如果你购买了虚拟主机服务,但是你的服务商确禁止你修改这个文件。那么,你可以需要考虑用其他方法来增加memory_limit的值。
那么我们要怎么从程序的根本上来解决这个问题呢,请往下看:
PHP开发过程中,高手都会用unset来释放内存,开始也没有深入了解,就跟着用,当然不是所有变量都unset,因为开发这么久了,也没感觉不unset有问题,但是最近的一个程序频繁出问题,总是内存不够用,为是么我知道内存不够用呢,因为使用ini_set(‘memory_limit’, ’2000M’);增加内存以后,程序就正常了,所以很明显,内存不够用,但是PHP不是会释放内存的吗,为是么会导致内存不够呢,没错,PHP是会释放内存,但是是每个函数执行完释放一次,整个程序跑完才能完全释放,而为了采集,每个程序都由许多函数来跑,这些函数有的使用内存过多,还没能等到执行完毕释放内存,就死掉了,整个程序也就中断了,下面看几个例子,会有更深的体会。
function test()
{
echo memory_get_usage().” test函数开始使用内存\n”;
$a[]=’a';
unset($a);
echo memory_get_usage().” 给数组a赋值后使用内存\n”;
$b[]=’b';
unset($b);
echo memory_get_usage().” 给数组b赋值后使用内存\n”;
$c[]=’c';
unset($c);
echo memory_get_usage().” 给数组c赋值后使用内存\n”;
}
echo memory_get_usage() . ” PHP读入当前文件所用内存,代码越多,内存占用越多\n”;
test();
echo memory_get_usage() . ” 运行完test函数所用内存\n”;
test();
echo memory_get_usage() . ” 再运行一次test函数所用内存\n”;
?>
结果:
321124 PHP读入当前文件所用内存,代码越多,内存占用越多
321144 test函数开始使用内存
321144 给数组a赋值后使用内存
321144 给数组b赋值后使用内存
321144 给数组c赋值后使用内存
321144 运行完test函数所用内存
321144 test函数开始使用内存
321144 给数组a赋值后使用内存
321144 给数组b赋值后使用内存
321144 给数组c赋值后使用内存
321144 再运行一次test函数所用内存
function test()
{
echo memory_get_usage().” test函数开始使用内存\n”;
$a[]=’a';
//unset($a);
echo memory_get_usage().” 给数组a赋值后使用内存\n”;
$b[]=’b';
//unset($b);
echo memory_get_usage().” 给数组b赋值后使用内存\n”;
$c[]=’c';
//unset($c);
echo memory_get_usage().” 给数组c赋值后使用内存\n”;
}
echo memory_get_usage() . ” PHP读入当前文件所用内存,代码越多,内存占用越多\n”;
test();
echo memory_get_usage() . ” 运行完test函数所用内存\n”;
test();
echo memory_get_usage() . ” 再运行一次test函数所用内存\n”;
?>
结果:
320896 PHP读入当前文件所用内存,代码越多,内存占用越多
320916 test函数开始使用内存
321120 给数组a赋值后使用内存
321324 给数组b赋值后使用内存
321528 给数组c赋值后使用内存
320916 运行完test函数所用内存
320916 test函数开始使用内存
321120 给数组a赋值后使用内存
321324 给数组b赋值后使用内存
321528 给数组c赋值后使用内存
320916 再运行一次test函数所用内存
从以上结果得知:
1.函数内不unset变量的话内存会越用越多,但是这个占用是一时的,这个函数一执行完这些内存就会释放,所以不会导致整个程序占用内存过多,这就需要保证一个函数不能使用内存过多,否则超过额定内存(PHP的额定内存一般设置为38M,可以通过ini_set(‘memory_limit’, ’2000M’)设置),程序就会退出。
2.函数内unset了变量,对于整个程序来说占用的内存更多,不unset反而用得少,这是是么原因呢,我个人觉得,从宏观角度来说,我们不去观察函数,而是把函数看成是一个操作,那这个操作内容越多,占用的内存就越多,所以执行unset这个操作后,使用的内存反而更多,当然,这个内存的增加是可以忽略不计的,而函数内部的变量如果很大的话,不unset的话,可能执行这个函数的时候就卡死在那里了,所以unset还是必须的
3.最后查了很多资料,了解到,在PHP4年代,PHP执行是内存不够用再向系统要,用完了再给回系统,所以内存占用从任务管理器里面可以很清楚的看到,但是PHP5之后,PHP执行的时候会先向系统征用一块大内存,然后自己管理,超过这个内存程序再向系统要,所以在任务管理器是看不出程序执行时内存使用情况的,这也导致很多人觉得unset可用可不用
---------------------
作者:Sunface撩技术
来源:CSDN
原文:https://blog.csdn.net/erlib/article/details/38488825
版权声明:本文为博主原创文章,转载请附上博文链接!
PHP脚本占用内存太多,解决方案的更多相关文章
- Unity3D占用内存太大的解决方法
原地址:http://www.cnblogs.com/88999660/archive/2013/03/15/2961663.html 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大 ...
- (转)Unity3D占用内存太大的解决方法
自:http://www.cnblogs.com/88999660/archive/2013/03/15/2961663.html 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. ...
- Unity3D占用内存太大怎么解决呢?
最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个 ...
- php 因循环数据 赋值变量 占用内存太大 提示错误
Fatal error: Allowed memory size of 134217728 bytes exhausted 网上很多解决方法:就简单记录下 一个csv导入功能 由于数据太多 占用内存太 ...
- 【转载】Unity 优雅地管理资源,减少占用内存,优化游戏
转自:星辰的<Unity3D占用内存太大的解决方法> 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D ...
- linux c++应用程序内存高或者占用CPU高的解决方案_20161213
对于绝大多数实时程序来说,实时处理相关程序中的循环问题所带来的对机器的损耗和自身的处理速度的平衡,以及与其他程序的交互以及对其他功能的影响难免会成为程序设计中最大的障碍同时也是最大的突破点. 在所有这 ...
- Centos环境自写脚本查看使用php或nginx占用内存
在CentOs6.4下,用root权限测试. # cd ~ //进入home目录 # vim .bashrc //编辑文件,把下面代码放入地址 mem () { top -n1 -b | head - ...
- Linux的php-fpm优化心得-php-fpm进程占用内存大和不释放内存问题(转)
原文地址:https://wzfou.com/php-fpm/ 最近发现博客的内存老是隔三差五地被“吃掉”了,登录到后台后偶尔会出卡顿的情况,一开始怀疑是Swap不够导致的,于是给VPS主机增加了几个 ...
- 解决Apache长时间占用内存大的问题,Apache 内存优化方法
问:为什么服务器在连续运行多天后或访问峰值后,进程中的一个Apache.exe占用内存几百兆不减少?答:用记事本打开apache2\conf\httpd.conf,我在centos5上装了kloxo, ...
随机推荐
- 详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化
在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子详解这两个函数的作用. 1. ...
- Aws s3 api
PUT操作的这个实现将一个对象添加到一个bucket中. 您必须具有对bucket的WRITE权限才能向其中添加对象. Amazon S3从不添加部分对象; 如果您收到成功响应,则Amazon S3将 ...
- keys()
keys():返回一个数组,里面是符合匹配模式的键列表 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $pattern = ...
- threading学习
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...
- css总结4:input 去掉外边框,placeholder的字体颜色、字号
1 input 标签去除外边框: 在进行webAPP开发时,input外边框非常影响美观,去除外边框方法如下: <input style="border: 0px;outline:no ...
- iOS CocoaPods安装与使用 好东西保存
http://www.cnblogs.com/daguo/p/4097263.html http://www.cnblogs.com/pican/p/3939941.html?utm_source=t ...
- 观察者(Observer)模式 * 委托事件
观察者(Observer)模式:定义了一种一对多的依赖关系.让多个观察者对象同时监听某一个主题对象. 这个主题对象发生变化时会通知所有观察者对象,使他们字段更新自己 /* * 抽象主题(Subje ...
- SQL 2005报错之Restore fail for Server 'DatabaseServerName'.
Restore fail for Server 'DatabaseServerName'.(Microsoft.SqlServer.Smo) Additional information: Syste ...
- 搜索引擎Hoot的源码阅读(提供源码)
开门见山,最近阅读了一下一款开源引擎的源码,受益良多(学到了一些套路).外加好久没有写博客了(沉迷吃鸡,沉迷想念姑娘),特别开一篇.Hoot 的源码地址, 原理介绍地址.外加我看过之后的注释版本,当然 ...
- Vue watch用法
Vue.js 提供了一个方法 watch,它用于观察Vue实例上的数据变动.对应一个对象,键是观察表达式,值是对应回调.值也可以是方法名,或者是对象,包含选项. 例如,同一个组件切换时,不会触发生命周 ...