java.lang.OutOfMemory

 常见问题解答 > 错误 > 异常 > java.lang.OutOfMemory

好的,这是可以处理的。可以配置几乎所有 ActiveMQ Classic 的内存使用情况。首先要确定的是系统中哪个部分内存不足。是 JVM、代理、消费者还是生产者?

此条目适用于 ActiveMQ Classic 5.1.x 及更高版本。

内存

JVM 内存

尝试使用 bin/activemq 在独立 JVM 中运行代理。请注意脚本传递给 Java 可执行文件的默认 JVM 堆大小选项(确切的选项可能取决于您使用的 JVM,以下示例适用于 Sun JVM)。

  • -Xmx:如果您的操作系统有更多可用内存,请考虑增加代理 JVM 可用的总堆内存。请注意,JVM 将需要比 -Xmx 值更多的内存。线程堆栈和 JMVs 内部类将占用额外的内存。
  • -Xss:如果您在代理 JVM 中有 大量线程,请考虑使用 -Xss 选项减少每个线程的默认 JVM 堆栈大小。

如果您运行的是嵌入式代理或第三方容器,请确保托管 JVM 具有适合最大堆大小和堆栈大小的值。

代理内存

代理允许使用的内存量并非由分配给 JVM 的内存量决定。尽管代理受 JVM 给予的内存量限制,但代理会独立管理其内存。也就是说,代理不会简单地使用掉 JVM 中的所有内存,然后以 OutOfMemory 异常死亡。这就是您需要了解 systemUsage 内存限制和每个目标的内存限制的地方。

ActiveMQ Classic 中的内存以分层方式工作,从 JVM -> 代理 -> 代理功能。例如,放置的总目标内存限制不能超过代理的内存限制。

消费者

除了消息大小之外,预取限制 是消费者 内存不足 的主要原因。降低预取值将减少消费者内存中排队/存储的消息数量。

生产者

除非消息大小超过资源限制,否则生产者不应出现内存不足。生产者可能会注意到代理执行内存限制的影响,表现为 阻塞

其他

将消息分页到磁盘

只有当消息存储在内存中时,才能快速分发消息。当消费者速度慢或不存在时,内存会很快耗尽。
代理(使用 消息游标)将在到达目标的默认内存使用阈值时将非持久消息分页到磁盘。此阈值是通过以下内容指定给代理的部分[activemq.xml](xml-configuration) 中的配置。此功能允许生产者在有速度慢的消费者时继续发送消息,而不会耗尽可用内存或恢复到 [生产者流量控制](producer-flow-control)。在多个目标的情况下,组合的默认内存阈值可能过高,它们可能会超过可用内存。在这种情况下,可能需要减少将消息分页到磁盘时的内存使用“限制”阈值。另一种选择是配置“precentUsage”而不是绝对使用“限制”。这样,内存使用就可以限制在可用内存的固定百分比内。

可以在 activemq.xml 中使用 每个目标策略 指定更具体的每个目标 memoryUsage 限制。[消息游标](message-cursors) 参考中提供了有关映射项的更多示例。

线程数量

默认情况下,ActiveMQ Classic 为每个目标使用一个专用线程。如果目标数量很多,将有大量线程及其关联的内存资源使用情况。可以通过使用系统属性将 ActiveMQ Classic 配置为使用线程池:-Dorg.apache.activemq.UseDedicatedTaskRunner=false。这目前在 activemq 启动脚本中通过 ACTIVEMQ_OPTS 指定。使用线程池可以限制 ActiveMQ Classic 需要的线程数量,从而减少内存使用。

非常大的消息

当您的消息非常大,以至于您一次只能允许少量消息在内存中时,每个目标策略 maxPageSize 和 lazyDispatch 可以提供帮助。maxPageSize 控制分页到内存以进行分发的消息数量,而 lazyDispatch 使用当前消费者列表的预取容量来增加该值。对于预取值为 1、单个消费者和 lazyDispatch,一次只会将一条消息加载到内存中。

泄漏 JMS 资源

这对消费者或生产者来说是最明显的;反复获取 Session 或 MessageProducer 或 MessageConsumer 而不关闭它。对于 java.lang.OutOfMemory,验证(再次)所有未使用的 JMS 资源是否已释放是值得的。如果您的应用程序中有多个线程,请考虑使用 PooledConnectionFactory,因为它允许安全地在遵循以下模式的线程之间共享 JMS 资源

obtainJmsResource(); 

try 
{ 
    useJmsResource() 
} finally { 
    releaseJmsResource(); 
} 

如果您通过 Spring 支持 或使用 JMSTemplates 使用 ActiveMQ Classic,请确保您没有遇到任何 JmsTemplate 陷阱。可能还值得回顾一下 如何有效使用 JMS

Apache、ActiveMQ、Apache ActiveMQ、Apache 羽毛标志和 Apache ActiveMQ 项目标志是 Apache 软件基金会的商标。版权所有 © 2024,Apache 软件基金会。根据 Apache 许可证 2.0 许可。