|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2012-02-16 17:33 UTC] jpauli@php.net
 Description: ------------ For what I investigated, it's not related to ext/amqp but it's in librabbitmq; well I think, I'm not sure So my script has a simple publisher, and no consumer (not needed, just fill data in a rabbitMQ server). It just publishes to a queue, in Direct mode, with one routing key. Easy. I have a loop feeding some few data (few bytes, each publish() is fed few bytes ). The loop has 5000 iterations. It may have more, but then I have not enough memory and start swaping / OOMing IMPORTANT : Using AMQP_IMMEDIATE in publish() triggers the leak. Not using AMQP_IMMEDIATE in publish() is all right. For what I noticed using callgrind, massif and memcheck, when using AMQP_IMMEDIATE, all the payload is delayed and actually really sent at shutdown, allocating lots of buffers for each data and not freeing them immediately, which might OOM the machine. When not using AMQP_IMMEDIATE, the buffers seem to be allocated, sent, then freed immediately; thus no memory overhead. Here are the results : https://gist.github.com/1846541 The callgrind schemas are actually very interesting, as they clearly show that a memory starvation happens when PHP is shutting down using AMQP_IMMEDIATE which does not happen when not using AMQP_IMMEDIATE https://gist.github.com/1846607 Test script: --------------- class Publisher { protected $channel; protected $connection; protected $name; protected $queue; public function __construct($exchangeName) { $this->connection = new \AMQPConnection(array('host'=>'127.0.0.1', 'port'=>5672, 'login'=>'guest', 'password'=>'guest')); $this->connection->connect(); $this->channel = new \AMQPChannel($this->connection); $this->exchange = new \AMQPExchange($this->channel); $this->exchange->setName($this->name = $exchangeName); $this->exchange->setType(AMQP_EX_TYPE_DIRECT); $this->exchange->setFlags(AMQP_DURABLE); $this->exchange->declare(); } public function sendSQLJob($sql) { $this->exchange->publish($sql, 'sqlkey', AMQP_IMMEDIATE); } } require __DIR__ . '/config.php'; $i=0; $j = 5000; $publisher = new Publisher('sql'); $fp = fopen('some/text/file', 'r'); while($sql = fgets($fp) && --$j) { $publisher->sendSQLJob($sql); printf("\r%d \r", $i++); } unset($publisher); Expected result: ---------------- memory level normal Actual result: -------------- memory consumption very high but not a leak as all buffers get freed, they simply seem to stack in a loop thus blowing up the memory PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 05:00:02 2025 UTC | 
Same here with AMQPQueue::declare() $con = new AMQPConnection(); $con->connect(); $ch = new AMQPChannel($con); $q = new AMQPQueue($ch); $q->setName('test'); while(true) { $q->declare(); }Same here even without this flag set. Just doing normal publish in a loop i.e. for($i=0;$i<1000;$i++){ $con = new AMQPConnection(); $con->pconnect(); $ch = new AMQPChannel($con); $e = new AMQPExchange($ch); ... $e->publish('test'); } I noticed that replacing pconnect() connect solved that.Maybe this is a different bug, i don't know.