1

When using ActiveMQ-cpp all of the ActiveMQ clients that are created and send messages using cms::MessageProducer gradually increase the memory usage. Right now that looks to be about 4Kb per message send. There does not appear to be any memory leaks with valgrind and the memory increase will continue until the program is terminated or uses all available system memory.

The memory increase happens when the messages are sent and not received by any other ActiveMQ client and when messages are just sent by the producer with no other consumer. It also appears that the act of creating a producer can lead to the memory increase. Here is example code of a call to Publish that leads to the memory increase. I have also tried just using a member session_ variable that is used to create destinations and producers instead of creating a new session every time.

void ActiveMqClient::Publish(std::string type,
                             void* input, size_t len) {
  if(type == "") {
    ead::eadwarn() << "ActiveMqClient::Publish() - Attempting to publish to "
      "empty string topic. Please check your message topic." << std::endl;
  }
  cms::Session* session = connection_->createSession(
      cms::Session::AUTO_ACKNOWLEDGE);
  //creates a destination and producer
  cms::Destination* destination(session->createTopic(type));
  cms::MessageProducer* producer(session->createProducer(destination));
  producer->setDeliveryMode(cms::DeliveryMode::PERSISTENT);
  //creates message and sets properties
  std::unique_ptr<cms::BytesMessage> message(session->createBytesMessage());
  //gets byte array from input
  size_t size_to_write = 0;
  unsigned char* body = (unsigned char*) input;
  if(io_handler_ != nullptr) {
    body =
      io_handler_->ConvertBodyForPublish(type, input, &len, &size_to_write);
  }
  //writes the bytes of input
  message->writeBytes(const_cast<const unsigned char*>(body), 0,
                      size_to_write);
  //gets byte array from input
  unsigned char* payload = (unsigned char*) input;
  if(io_handler_ != nullptr) {
    payload = io_handler_->ConvertPayloadForPublish(type,
        input,
        len,
        &size_to_write);
  }
  //writes the bytes of input
  if (size_to_write != 0) {
    message->writeBytes(payload, 0, size_to_write);
  }
  //sets the message type of the message
  message->setStringProperty("MsgType", type);
  //sets the message size
  message->setIntProperty("size", len);
  //sets the byte pointer to the beginning of the byte array
  message->reset();
  producer->send(message.get());
  //calls sentcallback if it exists
  if(io_handler_ != nullptr) {
    io_handler_->HandleMessageSent(type, reinterpret_cast<char*>(body), len);
  }
  //clears memory
  delete producer;
  delete destination;
  delete session;
}

So any ideas on why the memory would steadily keep increasing when utilizing the MessageProducer in this way. No matter how I use this pattern it seems to keep increasing the memory use. Thanks in advance for any help with this!

physnicm
  • 11
  • 1
  • I am interested in this too. – coderunner Mar 19 '18 at 22:42
  • 1
    Have you tried running Valgrind? Activemq-cpp is an utter disaster C++-wise (like just about every other C++ package from Apache). Everything is (needlessly) heap allocated, so a missing delete in that sprawling mass of wannabe-Java code wouldn't be surprising at all. – arayq2 Sep 24 '20 at 12:54
  • 1
    Memory fragmentation is very likely with pseudo-Java (the "C++" in activemq-cpp). You avoid this by sticking to a stack-like discipline with allocations and releases. In your example code, you should have used unique_ptr with _all_ of the objects. Without that, the `BytesMessage` will be released _last_ instead of first at the end of the function, which could create a "fragementation hole" in the memory allocator. More generally, new-ing and delete-ing willy nilly is very bad C++ to begin with, and should be reconsidered. – arayq2 Jul 18 '21 at 03:02
  • Thank you for taking the time to answer this! The memory leak was not caught with valgrind but rather with monitoring htop and watching every program which used the ActiveMQ-cpp broker ratchet up memory usages without ever going back down. I pivoted with this and ended up sticking with a ZMQ implementation with IPC sockets. – physnicm Jul 20 '21 at 00:33

0 Answers0