我正在尝试写一个Laravel函数,从一个数据库获取大量记录(100,000),并将其放在另一个数据库中。为此,我需要查询我的数据库,看看用户是否已经存在。我反复称这个代码: $users = U
$users = User::where('id', '=', 2)->first();
然后在那之后发生了几百次,我用完了内存。所以,我做了一个简单的例子,它使用了所有可用的内存,它看起来像这样:
<?php use Illuminate\Console\Command; class memoryleak extends Command { protected $name = 'command:memoryleak'; protected $description = 'Demonstrates memory leak.'; public function fire() { ini_set("memory_limit","12M"); for ($i = 0; $i < 100000; $i++) { var_dump(memory_get_usage()); $this->external_function(); } } function external_function() { // Next line causes memory leak - comment out to compare to normal behavior $users = User::where('id', '=', 2)->first(); unset($users); // User goes out of scope at the end of this function } }
并且这个脚本的输出(由“php工匠命令:memoryleak”执行)看起来像这样:
int(9298696) int(9299816) int(9300936) int(9302048) int(9303224) int(9304368) .... int(10927344) int(10928432) int(10929560) int(10930664) int(10931752) int(10932832) int(10933936) int(10935072) int(10936184) int(10937320) .... int(12181872) int(12182992) int(12184080) int(12185192) int(12186312) int(12187424) PHP Fatal error: Allowed memory size of 12582912 bytes exhausted (tried to allocate 89 bytes) in /Volumes/Mac OS/www/test/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 275
如果我注释掉“$ users = User :: where(‘id’,’=’,2) – > first();”那么内存使用情况保持稳定。
有没有人有任何见解,为什么这条线会使用这样的记忆,或者知道一个更聪明的方式来完成我想要做的事情?
感谢您的时间。
我重新创建了你的脚本,并通过一个调试器,因为我不能理解什么样的可怕的事情会导致这种类型的内存问题。当我走过来,我遇到了这个:// in Illuminate\Database\Connection $this->queryLog[] = compact('query', 'bindings', 'time');
您在Laravel中运行的每个查询似乎都存储在一个持久性日志中,这样可以解释每次查询后内存使用量的增加。就在这之上,是如下所示:
if ( ! $this->loggingQueries) return;
更多的挖掘确定了loggingQueries属性默认设置为true,并且可以通过disableQueryLog方法更改,这意味着,如果您调用:
DB::connection()->disableQueryLog();
在您执行所有查询之前,您将看不到内存使用量的增加;当我根据您的示例代码运行我的测试时,它解决了问题。完成后,如果您不想影响可以调用的其余应用程序
DB::connection()->enableQueryLog();
到可记录日志。