zoukankan      html  css  js  c++  java
  • 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函数开始使用内存 ”;

        $a[]=’a';
        unset($a);
        echo memory_get_usage().”    给数组a赋值后使用内存 ”;

        $b[]=’b';
        unset($b);
        echo memory_get_usage().”    给数组b赋值后使用内存 ”;

        $c[]=’c';
        unset($c);
        echo memory_get_usage().”    给数组c赋值后使用内存 ”;
        }

        echo memory_get_usage() . ”    PHP读入当前文件所用内存,代码越多,内存占用越多 ”;
        test();
        echo memory_get_usage() . ”    运行完test函数所用内存 ”;
        test();
        echo memory_get_usage() . ”    再运行一次test函数所用内存 ”;
        ?>

    结果:

    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函数开始使用内存 ”;

        $a[]=’a';
        //unset($a);
        echo memory_get_usage().”    给数组a赋值后使用内存 ”;

        $b[]=’b';
        //unset($b);
        echo memory_get_usage().”    给数组b赋值后使用内存 ”;

        $c[]=’c';
        //unset($c);
        echo memory_get_usage().”    给数组c赋值后使用内存 ”;
        }

        echo memory_get_usage() . ”    PHP读入当前文件所用内存,代码越多,内存占用越多 ”;
        test();
        echo memory_get_usage() . ”    运行完test函数所用内存 ”;
        test();
        echo memory_get_usage() . ”    再运行一次test函数所用内存 ”;
        ?>

    结果:

    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
    版权声明:本文为博主原创文章,转载请附上博文链接!

     
     
     
     
  • 相关阅读:
    hdu 4521 小明系列问题——小明序列(线段树 or DP)
    hdu 1115 Lifting the Stone
    hdu 5476 Explore Track of Point(2015上海网络赛)
    Codeforces 527C Glass Carving
    hdu 4414 Finding crosses
    LA 5135 Mining Your Own Business
    uva 11324 The Largest Clique
    hdu 4288 Coder
    PowerShell随笔3 ---别名
    PowerShell随笔2---初始命令
  • 原文地址:https://www.cnblogs.com/applelife/p/10481368.html
Copyright © 2011-2022 走看看