我正在使用laravel 5.1和supervisor来监控队列作业。队列驱动程序为数据库。
[program:queue]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/artisan queue:work database --sleep=3 --tries=1 --daemon
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/supervisord.log在处理每个作业之后,队列侦听器使用的RAM会增加,并且会达到150-200MB。所有全局变量都被赋值为null。
namespace App\Jobs;
use App\Jobs\Job;
use App\Compatibility;
use App\Like;
use App\Message;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
class CalculateInteractionLike extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $userAId;
protected $userBId;
protected $gender;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($userAId, $userBId, $gender)
{
$this->userAId = $userAId;
$this->userBId = $userBId;
$this->gender = $gender;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
echo 'start CalculateInteractionLike '. memory_get_usage() . "\n";
$userArray = array();
Compatibility::where('userAId', $this->userBId)->where('userBId', $this->userAId)->update(['interactionAB'=>0.0001]);
$profiles = Compatibility::where('userAId', $this->userBId)->where('interactionAB', '>',0)->orderBy('compatibilityAB', 'desc')->take(4)->get(['compatibilityAB']);
$compatible = array();
for($i=0; $i<sizeof($profiles);$i++){
$compatible[] = $profiles[$i]->compatibilityAB;
}
$std = sizeof($compatible)>1 ? $this->_calculateStd($compatible) : 0;
$messagedProfile = Message::where('userBId', $this->userBId)->where('type', '1')->get(['userAId']);
for($i=0;$i<sizeof($messagedProfile);$i++){
Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
}
$this->userAId = null;
$this->userBId = null;
$this->gender = null;
$userArray = null;
$profiles = null;
$compatible = null;
$std = null;
$messagedProfile = null;
}
private function _calculateStd($compatible){
return sqrt(array_sum(array_map([$this,"_stdSquare"], $compatible, array_fill(0,count($compatible), (array_sum($compatible) / count($compatible))))) / (count($compatible)-1));
}
private static function _stdSquare($x, $mean){
return pow($x - $mean, 2);
}
public function __destruct(){
$this->cleanup();
echo 'end CalculateInteractionLike '. memory_get_usage() . "\n";
}
public function cleanup() {
//cleanup everything from attributes
foreach (get_class_vars(__CLASS__) as $clsVar => $_) {
unset($this->$clsVar);
}
}
}如果处理了上述作业,则每次都会增加一些RAM。有什么想法吗?
发布于 2017-05-07 07:03:09
作为一种解决办法-如果您找不到内存泄漏的来源-您可以直接切换到不带任何守护程序标志的queue:listen。
这将在每次作业后“重启”框架,由PHP释放所有内存。
这与Supervisor兼容,可确保queue:listen始终重新启动。
发布于 2016-09-09 03:32:36
唯一不清除内存的地方是在内存中的for()
for($i=0;$i<sizeof($messagedProfile);$i++){
Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
}第一个是静态的(::used),但是在内部创建了对象,并且开始使用->调用函数。您是否尝试检查是否有派生程序并手动调用垃圾收集器?
for($i=0;$i<sizeof($messagedProfile);$i++){
Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
gc_collect_cycles();
}第二件事,where(),update()等可以返回对象上的引用,所以如果是,你可以尝试一下:
for($i=0;$i<sizeof($messagedProfile);$i++){
$tmp = Compatibility::where('userAId',$this->userBId)->where('userBId', $messagedProfile[$i]->userAId)->update(array('interactionAB' => $std));
$tmp = null;
}请注意,php < 7.0不会自动销毁在上层类中创建的类的对象。检查这个:https://codereview.stackexchange.com/questions/57847/case-of-the-hidden-memory-leak
https://stackoverflow.com/questions/39245190
复制相似问题