我在Docker中使用Karaf和ActiveMQ Artemis,我的一个路由在消息队列上获得XML字符串,我需要提取一个元素。但我得到了java.lang.OutOfMemoryError: Java heap space
我已经把问题缩小到其中一行。
public void process(Exchange exchange) throws Exception {
Object[] args = exchange.getIn().getBody(Object[].class);
JmsMessage message = (JmsMessage)args[0];
String s = message.getBody(String.class);
...
}
我想知道我的选择是什么来解决这个错误。
查看容器内的free -m
输出,
# free -m
total used free shared buff/cache available
Mem: 23948 11579 498 1316 11870 10690
Swap: 6143 240 5903
有10GB的可用内存加上6GB的交换空间。Artemis队列有<max-size-bytes>-1</max-size-bytes>
集合,没有<global-max-size>
集合。所以没有明确的限制。根据broker.xml
文件中的注释,这可能导致-Xmx / 2
的最大值。看起来默认值是-Xmx2G,所以这意味着最大1GB。请注意,消息远没有达到这个大小。它只是5MB的二进制文件,使用Base64保存为XML。
所以我将研究用更高的Xmx
开始AMQ,但否则,在Java中是否有任何选项来处理解析String
(或JMSMessage
),以这样一种方式,它不会溢出堆?
。比如流式传输,或者缓冲,而不是将整个字符串加载到内存中?
通过在/bin/setenv下增加Karaf可用的RAM修复了这个问题
export JAVA_MAX_MEM=2048M