activemq-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bwtaylor <>
Subject Re: VM transport not using pass-by-reference
Date Thu, 05 Jun 2008 05:34:24 GMT

I traced through some code. It looks like ActiveMQSession.send() does honor
copyMessageOnSend as noted. But this only explains why you see 2001, not
2002 messages. Message consumption on a topic happens in a two step process: 
 1) During dispatch, a MessageDispatch object is enqueued to consumer's
unconsumedMessage MessageDispatchChannel, then 
 2) During receive, the MessageDispatch is dequeued from unconsumedMessage

The message is dispatched via a call to
ActiveMQMessageConsumer.dispatch(MessageDispatch md). If the consumer has a
MessageListener, a copy of the message is sent to it after calls to
createActiveMQMessage(md) and listener.onMessage(message). Then the original
is enqueued to unconsumedMessage. I don't think you actually have such a
listener, so there's a 3rd copy out there that you are missing out on :-)
The copy happens on the first line of createActiveMQMessage:

    private ActiveMQMessage createActiveMQMessage(final MessageDispatch md)
throws JMSException {
        ActiveMQMessage m = (ActiveMQMessage)md.getMessage().copy();
        [... stuff omitted]
        return m;

The dispatch call happens after a long sequence of dispatch calls that go
all the way back to the ActiveMQConnection object. It's onCommand() method
uses a visitor pattern and the CommandVisitorAdapter it uses has this

                    public Response processMessageDispatch(MessageDispatch
md) throws Exception {
                        ActiveMQDispatcher dispatcher =
                        if (dispatcher != null) {
                            // Copy in case a embedded broker is dispatching
                            // vm://
                            // md.getMessage() == null to signal end of
                            // browse.
                            Message msg = md.getMessage();
                            if (msg != null) {
                                msg = msg.copy();
                        return null;

According to the comment, this copy is a feature of vm:// transport not a
bug :-)

The other copy is easier to find. When the message is consumed we instead
get a call to ActiveMQMessageConsumer.receive(), which dequeues a
MessageDispatch md from the MessageDispatchChannel unconsumedMessages then
and calls createActiveMQMessage(md), which as we saw above makes a copy.

So 1 copy on dispatch, 1 copy on receive, and a 3rd copy onMessage() if the
consumer has a listener. I have no insight into the motivations here, I just
eyeballed the code and described the relevant parts.

Some good news: message.copy() is a shallow copy: the content (and
everything else) within the message is copied by reference. See
org.apache.activemq.command.Message.copy(Message copy) .
View this message in context:
Sent from the ActiveMQ - User mailing list archive at

View raw message