blob: f8d470b20d2046baedc417f6bb64a153e8e82737 [file] [log] [blame]
<div class="wiki-content maincontent"><p>Ok, this is manageable. It is possible to configure just about all of the memory utilisation of ActiveMQ. The first thing to determine is what part of the system is running out of memory. Is it the JVM, the broker, the consumers or the producers? </p>
<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
<p>This entry refers to ActiveMQ versions 5.1.x and greater.</p></div></div>
<h4 id="java.lang.OutOfMemory-Memory">Memory</h4>
<h5 id="java.lang.OutOfMemory-JVMMemory">JVM Memory </h5>
<p>Try running the broker in a standalone JVM using <code>bin/activemq</code>. Note the default JVM heap size option that is passed to the Java executable by the script (the exact options may depend upon the JVM that you are using, the examples are for the Sun JVM).</p>
<ul><li>-Xmx: If your OS has more available memory, consider increasing the total heap memory available to the broker JVM. Note that the JVM will require more memory than the -Xmx value. Thread stacks and the JMVs internal classes will consume additional memory.</li><li>-Xss: If you have <a shape="rect" href="javalangoutofmemory.html">massive numbers of threads</a> in the Broker JVM, consider reducing the default JVM stack size of each thread with the -Xss option.</li></ul>
<p>If you are running an embedded broker or in a third party container, ensure that the hosting JVM has appropriate values for the maximum heap and stack sizes.</p>
<h5 id="java.lang.OutOfMemory-BrokerMemory">Broker Memory </h5>
<p>The memory that the broker is allowed to use is not determined by the amount of memory allocated to the JVM. Although the broker is constrained by the amount of memory given to the JVM, the broker manages its memory independently. That is, the broker does not just simply use up all of the memory in the JVM and then die with an OutOfMemory exception. This is where you need to understand the <a shape="rect" href="producer-flow-control.html">systemUsage</a> memory limit and the per destination memory limit. </p>
<p>The memory in ActiveMQ works in a tiered fashion that flows from the JVM -&gt; Broker -&gt; broker features. E.g., the total amount of destination memory limits placed cannot exceed the memory limit of the broker. </p>
<h4 id="java.lang.OutOfMemory-Consumer">Consumer</h4>
<p>Along with message size, the <a shape="rect" href="what-is-the-prefetch-limit-for.html">prefetch limit</a> is main reason a consumer will <a shape="rect" href="what-is-the-prefetch-limit-for.html">run out of memory</a>. Reducing the prefetch value will reduce the amount of messages queued/stored in memory on the Consumer.</p>
<h4 id="java.lang.OutOfMemory-Producer">Producer</h4>
<p>Unless message size exceeds resource limits, a producer should not run out of memory. A producer may notice the effect of memory limit enforcement by the broker in the form of <a shape="rect" href="my-producer-blocks.html">blocking</a>.</p>
<h4 id="java.lang.OutOfMemory-Other">Other </h4>
<h5 id="java.lang.OutOfMemory-SpoolingMessagestoDisk">Spooling Messages to Disk</h5>
<p>Fast dispatch of messages is only possible when messages are stored in memory. When consumers are slow or absent, memory can quickly become exhausted. <br clear="none">
The Broker (using <a shape="rect" href="message-cursors.html">Message Cursors</a>) will spool non-persistent messages to disk when the default memory usage threshold for a destination is reached. This threshold value is specified to the Broker via the &lt;memoryUsage&gt; section of the &lt;systemUsage&gt; configuration in <a shape="rect" href="xml-configuration.html">activemq.xml</a>. This feature allows producers to continue sending messages when there are slow consumers without exhausting available memory or reverting to <a shape="rect" href="producer-flow-control.html">producer flow control</a>. In the case of multiple destinations, the combined default memory thresholds may be excessive and they may exceed available memory. In such a case it may make sense to reduce the memory usage 'limit' threshold at which messages are spooled to disk. An alternative option is to configure the 'precentUsage' rather than the absolute usage 'limit'. In this way, memory usage can be confined to a fixed percentage of available memory.</p>
<p>More specific per destination memoryUsage limits can be specified in <a shape="rect" href="xml-configuration.html">activemq.xml</a> using <a shape="rect" href="per-destination-policies.html">Per Destination Policies</a>. Some further examples of &lt;destinationPolicy&gt; map entries can be found in the <a shape="rect" href="message-cursors.html">Message Cursors</a> reference.</p>
<h5 id="java.lang.OutOfMemory-NumberofThreads">Number of Threads</h5>
<p>By default, ActiveMQ uses a dedicated thread per destination. If there are large numbers of Destinations there will be a large number of threads and their associated memory resource usage. ActiveMQ can be configured to use a thread pool through the use of the system property: -Dorg.apache.activemq.UseDedicatedTaskRunner=false. This is currently specified in the activemq start script via ACTIVEMQ_OPTS. Using a thread pool can restrict the number of threads required by ActiveMQ and hence reduce memory usage.</p>
<h5 id="java.lang.OutOfMemory-ReallyLargeMessages">Really Large Messages</h5>
<p>When your message are really large such that you can only allow a few messages in memory at at time, the <a shape="rect" href="per-destination-policies.html">Per Destination Policies</a> maxPageSize and lazyDispatch can help. maxPageSize controls the amount of messages that are paged into memory for dispatch while lazyDispatch augments that value using the prefetch capacity of the current consumer list. With a prefetch of 1, a single consumer and lazyDispatch, only one message at a time would be loaded into memory at a time.</p>
<h5 id="java.lang.OutOfMemory-LeakingJMSresources">Leaking JMS resources</h5>
<p>This is the most obvious one for Consumers or Producers; repeatedly obtaining a Session or MessageProducer or MessageConsumer and not closing it. With a java.lang.OutOfMemory, verifying (again) that all not in use JMS resources are released, is worth the time. If you have multiple threads in your application, consider using the <a shape="rect" class="external-link" href="http://activemq.apache.org/maven/activemq-core/apidocs/org/apache/activemq/pool/PooledConnectionFactory.html">PooledConnectionFactory</a> as this will allow JMS resource to be safely shared among threads that follow the pattern: </p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">
obtainJmsResource();
try
{
useJmsResource()
} finally {
releaseJmsResource();
}
</pre>
</div></div>
<p>If you are using ActiveMQ via <a shape="rect" href="spring-support.html">Spring Support</a> or with JMSTemplates, be sure to check you are not falling for any of the <a shape="rect" href="jmstemplate-gotchas.html">JmsTemplate Gotchas</a>. It may also be worth recapping on <a shape="rect" href="how-do-i-use-jms-efficiently.html">How do I use JMS efficiently</a>.</p></div>