【问题标题】:PHP memory limit exhausted despite increasing尽管增加了PHP内存限制
【发布时间】:2014-10-03 09:26:57
【问题描述】:

我的网站上到处都出现以下错误:

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 600 bytes) in /classes/database.class.php on line 22

我尝试通过 ini_set 和 htaccess 增加内存限制,但仍然遇到同样的错误。

例如,提高到 128M 会导致内部服务器错误。

这是 database.class.php 的第 22 行(及周围):

private $host      = DB_HOST;
private $user      = DB_USER;
private $pass      = DB_PASS;
private $dbname    = DB_NAME;

private $dbh;
private $error;
private $stmt;

public function __construct(){
    // Set DSN
    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
    // Set options
    $options = array(
        PDO::ATTR_PERSISTENT    => true,
        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
    );
    // Create a new PDO instanace
    // line 22 now
    try{
        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
    }
    // Catch any errors
    catch(PDOException $e){
        $this->error = $e->getMessage();
    }
}

【问题讨论】:

  • 增加内存并不总是解决“内存不足”问题的方法:您需要找出正在使用所有内存的内容以及原因(通常是代码错误,例如无限循环)
  • 哪一行是第 22 行
  • 问题不太可能出现在这里,更有可能出现在实例化数据库类的某个地方
  • RiggsFolly 这并不重要,因为我认为这与 PDO 无关 pdo 不会像那样浪费大量内存。它必须发生在其他脚本中,这些脚本在读取文件或某些循环时会浪费大量内存。
  • 在你的代码中调用memory_get_usage(true),或者设置XHProf,它会为你生成一个很好的报告。不幸的是,错误消息本身只是告诉你压垮骆驼的最后一根稻草,而不是它已经携带的铅重物!

标签: php mysql .htaccess memory pdo


【解决方案1】:

如果您多次获取此对象,请像这样更改对象:

public function __construct(){
    $options = array(
                    'dsn' => 'mysql:host=' . $this->host . ';dbname=' . $this->dbname,
                    'user' => $this->user,
                    'pass' => $this->pass,
                    'options' => array( PDO::ATTR_PERSISTENT => true,
                                        PDO::ATTR_ERRMODE    => PDO::ERRMODE_EXCEPTION
                                      )
                    );
    $this->dbh = Db::factory("PDO",$options);
}

然后创建一个数据库工厂类:

final class Db {
   protected static $dbInstance;

   public static function factory($adapter,$options){
       if(!self::$dbInstance){
           self::$dbInstance = new $adapter($options['dsn'],$options['user'],$options['pass'],$options['options']);
       }

       return self::$dbInstance;
   }
}

这将有所帮助,并减少不必要的内存浪费和许多创建 PDO 实例的问题。

并在 PHP.ini 中或使用 PHP 更新您的内存限制:

ini_set("memory_limit","128M");

【讨论】:

  • 这当然是您应该获取 PDO 实例的方式,因为 php 脚本运行单线程,实际上没有理由为同一个数据库创建多个连接,但我仍然认为问题出在其他地方(你必须调用构造函数很多次才能达到 60MB+)
  • 他说他有很多函数使用对象,所以问题可能在这里,因为如果他同时创建很多实例,它会浪费所有内存。我们不知道他的代码,所以他可以有一个循环更新,他为任何循环创建实例。
【解决方案2】:

在错误消息67108864 bytes = 65Meg 中。因此,我建议您将内存限制增加到 128M,但它不起作用。

如果您在尝试增加限制时遇到内部服务器错误,那么您可能使用了不正确的语法。

.htaccess 文件中使用的语法是:-

php_value memory_limit 128M

在您的 PHP 脚本中使用的语法是:-

ini_set('memory_limit', '128M');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-24
    • 2010-11-26
    • 2015-08-31
    • 2014-06-28
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多